Skip to content

Commit

Permalink
Merge branch 'main' into min-ios14-swift-mig
Browse files Browse the repository at this point in the history
# Conflicts:
#	Test/Tests/ARTDefaultTests.swift
#	Test/Tests/ClientInformationTests.swift
#	Test/Tests/PushActivationStateMachineTests.swift
#	Test/Tests/RealtimeClientChannelTests.swift
#	Test/Tests/RealtimeClientConnectionTests.swift
#	Test/Tests/RealtimeClientPresenceTests.swift
#	Test/Tests/RealtimeClientTests.swift
  • Loading branch information
umair-ably committed Aug 5, 2024
2 parents 5708d9a + 7fceb3e commit 0d9af76
Show file tree
Hide file tree
Showing 37 changed files with 455 additions and 551 deletions.
21 changes: 21 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,26 @@
# Change Log

## [1.2.33](https://github.com/ably/ably-cocoa/tree/1.2.33)

[Full Changelog](https://github.com/ably/ably-cocoa/compare/1.2.32...1.2.33)

**What's Changed:**

- Attach according to RTL7c by @maratal in https://github.com/ably/ably-cocoa/pull/1935
- Enforce RTP6c attach rule for presence. by @maratal in https://github.com/ably/ably-cocoa/pull/1942
- Max message size fix by @maratal in https://github.com/ably/ably-cocoa/pull/1947
- Respect RSH3a3a by @maratal in https://github.com/ably/ably-cocoa/pull/1952

## [1.2.32](https://github.com/ably/ably-cocoa/tree/1.2.32)

[Full Changelog](https://github.com/ably/ably-cocoa/compare/1.2.31...1.2.32)

**Fixed issues:**

- Thread priority inversion runtime warning [\#1897](https://github.com/ably/ably-cocoa/issues/1897)

- Fix for ignored `ARTProtocolMessage.resumed` property [\#1920](https://github.com/ably/ably-cocoa/issues/1920)

## [1.2.31](https://github.com/ably/ably-cocoa/tree/1.2.31)

[Full Changelog](https://github.com/ably/ably-cocoa/compare/1.2.30...1.2.31)
Expand Down
24 changes: 10 additions & 14 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,23 +60,19 @@ To run tests use `make test_[iOS|tvOS|macOS]`. These tests expect you to have a
For each release, the following needs to be done:

* Create a new branch `release/x.x.x` (where `x.x.x` is the new version number) from the `main` branch
* Run `make bump_[major|minor|patch]` to bump the new version number (creates a Git commit)
* Run [`github_changelog_generator`](https://github.com/github-changelog-generator/github-changelog-generator) to automate the update of the [CHANGELOG](./CHANGELOG.md). This may require some manual intervention, both in terms of how the command is run and how the change log file is modified. Your mileage may vary:
* The command you will need to run will look something like this: `github_changelog_generator -u ably -p ably-cocoa --since-tag 1.2.9 --output delta.md`
* Using the command above, `--output delta.md` writes changes made after `--since-tag` to a new file
* The contents of that new file (`delta.md`) then need to be manually inserted at the top of the `CHANGELOG.md`, changing the "Unreleased" heading and linking with the current version numbers
* Also ensure that the "Full Changelog" link points to the new version tag instead of the `HEAD`
* Commit this change: `git add CHANGELOG.md && git commit -m "Update change log."`
* Push both commits to origin: `git push -u origin release/x.x.x`
* Run `make bump_[major|minor|patch]` to bump the new version number. This will create a Git commit, push it to origin: `git push -u origin release/x.x.x`
* Go to [Github releases](https://github.com/ably/ably-cocoa/releases) and press the `Draft a new release` button. Choose your new branch as a target
* Press the `Choose a tag` dropdown and start typing a new tag, Github will suggest the `Create new tag x.x.x on publish` option. After you select it Github will unveil the `Generate release notes` button
* From the newly generated changes remove everything that don't make much sense to the library user
* Copy the final list of changes to the top of the `CHANGELOG.md` file. Modify as necessary to fit the existing format of this file
* Commit these changes and push to the origin `git add CHANGELOG.md && git commit -m "Update change log." && git push -u origin release/x.x.x`
* Make a pull request against `main` and await approval of reviewer(s)
* Once approved and/or any additional commits have been added, merge the PR (f you do this from Github's web interface then use the "Rebase and merge" option)
* After merging the PR, wait for all CI jobs for `main` to pass.
* Checkout `main` locally, pulling in changes from above using `git checkout main && git pull`
* If any fixes are needed (e.g. the lint fails with warnings) then either commit them to `main` branch now if they are simple warning fixes or perhaps consider raising a new PR if they are complex or likely to need review.
* Create a tag for this version number using `git tag x.x.x`
* Push the tag using `git push origin x.x.x`
* Release an update for CocoaPods using `pod trunk push Ably.podspec`. Details on this command, as well as instructions for adding other contributors as maintainers, are at [Getting setup with Trunk](https://guides.cocoapods.org/making/getting-setup-with-trunk.html) in the [CocoaPods Guides](https://guides.cocoapods.org/)
* Add to [releases](https://github.com/ably/ably-cocoa/releases)
* If any fixes are needed (e.g. the lint fails with warnings) then either commit them to the `main` branch now (don't forget to pull the changes first `git checkout main && git pull`) if they are simple warning fixes or perhaps consider raising a new PR if they are complex or likely need a review.
* Publish your drafted release:
* refer to previous releases for release notes format
* attach to the release the prebuilt framework file (`Ably.framework.zip`) generated by Carthage – you can find this file in the `carthage-built-framework` artifact uploaded by the `check-pod` CI workflow
* Checkout `main` locally, pulling in changes using `git checkout main && git pull`. Make sure the new tag you need was created on publish
* Release an update for CocoaPods using `pod trunk push Ably.podspec`. Details on this command, as well as instructions for adding other contributors as maintainers, are at [Getting setup with Trunk](https://guides.cocoapods.org/making/getting-setup-with-trunk.html) in the [CocoaPods Guides](https://guides.cocoapods.org/)
* Test the integration of the library in a Xcode project using Carthage and CocoaPods using the [installation guide](https://github.com/ably/ably-cocoa#installation-guide)
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ You can install Ably for iOS and macOS through Package Manager, CocoaPods, Carth
- [This apple guide](https://developer.apple.com/documentation/swift_packages/adding_package_dependencies_to_your_app) explains the steps in more detail.
- To install the `ably-cocoa` package in another **Swift Package**, then add the following to your `Package.Swift`:
```swift
.package(url: "https://github.com/ably/ably-cocoa", from: "1.2.31"),
.package(url: "https://github.com/ably/ably-cocoa", from: "1.2.33"),
```
### Installing through [CocoaPods](https://cocoapods.org/)

Expand Down Expand Up @@ -101,7 +101,7 @@ If you see, for example, a `dyld: Library not loaded: @rpath/AblyDeltaCodec.fram

### Manual installation

1. Get the code from GitHub [from the release page](https://github.com/ably/ably-cocoa/releases/tag/1.2.31), or clone it to get the latest, unstable and possibly underdocumented version: `git clone [email protected]:ably/ably-cocoa.git`
1. Get the code from GitHub [from the release page](https://github.com/ably/ably-cocoa/releases/tag/1.2.33), or clone it to get the latest, unstable and possibly underdocumented version: `git clone [email protected]:ably/ably-cocoa.git`
2. Drag the directory `ably-cocoa/ably-cocoa` into your project as a group.
3. Ably depends on our [MessagePack Fork](https://github.com/ably-forks/msgpack-objective-C) 0.2.0; get it [from the releases page](https://github.com/ably-forks/msgpack-objective-C/releases/tag/0.2.0-ably-1) and link it into your project.

Expand Down
2 changes: 1 addition & 1 deletion Scripts/jazzy.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ jazzy \
--objc \
--clean \
--author Ably \
--module-version 1.2.31 \
--module-version 1.2.33 \
--umbrella-header Source/include/Ably/Ably.h \
--framework-root Source \
--module Ably \
Expand Down
2 changes: 1 addition & 1 deletion Source/ARTClientInformation.m
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#import <sys/utsname.h>

NSString *const ARTClientInformationAgentNotVersioned = @"ARTClientInformationAgentNotVersioned";
NSString *const ARTClientInformation_libraryVersion = @"1.2.31";
NSString *const ARTClientInformation_libraryVersion = @"1.2.33";
static NSString *const _libraryName = @"ably-cocoa";

// NSOperatingSystemVersion has NSInteger as version components for some reason, so mitigate it here.
Expand Down
10 changes: 9 additions & 1 deletion Source/ARTConnection.m
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
#import "ARTConnection+Private.h"

#import "ARTDefault.h"
#import "ARTRealtime+Private.h"
#import "ARTEventEmitter+Private.h"
#import "ARTQueuedDealloc.h"
#import "ARTRealtimeChannels+Private.h"
#import "ARTRealtimeChannel+Private.h"
#import "ARTDefault+Private.h"
#import "ARTClientOptions+Private.h"

#define IsInactiveConnectionState(state) (state == ARTRealtimeClosing || state == ARTRealtimeClosed || state == ARTRealtimeFailed || state == ARTRealtimeSuspended)

Expand Down Expand Up @@ -193,6 +195,12 @@ - (NSString *)key_nosync {
return _key;
}

- (NSInteger)maxMessageSize {
if (_maxMessageSize)
return _maxMessageSize;
return _realtime.options.isProductionEnvironment ? [ARTDefault maxProductionMessageSize] : [ARTDefault maxSandboxMessageSize];
}

- (ARTRealtimeConnectionState)state_nosync {
return _state;
}
Expand Down
35 changes: 32 additions & 3 deletions Source/ARTDefault.m
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
static NSString *const ARTDefault_realtimeHost = @"realtime.ably.io";

static NSTimeInterval _connectionStateTtl = 60.0;
static NSInteger _maxMessageSize = 65536;
static NSInteger _maxProductionMessageSize = 65536;
static NSInteger _maxSandboxMessageSize = 16384;

@implementation ARTDefault

Expand Down Expand Up @@ -70,7 +71,19 @@ + (NSTimeInterval)realtimeRequestTimeout {
}

+ (NSInteger)maxMessageSize {
return _maxMessageSize;
#if DEBUG
return _maxSandboxMessageSize;
#else
return _maxProductionMessageSize;
#endif
}

+ (NSInteger)maxSandboxMessageSize {
return _maxSandboxMessageSize;
}

+ (NSInteger)maxProductionMessageSize {
return _maxProductionMessageSize;
}

+ (void)setConnectionStateTtl:(NSTimeInterval)value {
Expand All @@ -81,7 +94,23 @@ + (void)setConnectionStateTtl:(NSTimeInterval)value {

+ (void)setMaxMessageSize:(NSInteger)value {
@synchronized (self) {
_maxMessageSize = value;
#if DEBUG
_maxSandboxMessageSize = value;
#else
_maxProductionMessageSize = value;
#endif
}
}

+ (void)setMaxProductionMessageSize:(NSInteger)value {
@synchronized (self) {
_maxProductionMessageSize = value;
}
}

+ (void)setMaxSandboxMessageSize:(NSInteger)value {
@synchronized (self) {
_maxSandboxMessageSize = value;
}
}

Expand Down
104 changes: 49 additions & 55 deletions Source/ARTEventEmitter.m
Original file line number Diff line number Diff line change
Expand Up @@ -176,8 +176,9 @@ - (instancetype)initWithQueues:(dispatch_queue_t)queue userQueue:(dispatch_queue
return self;
}

- (ARTEventListener *)on:(id<ARTEventIdentification>)event callback:(void (^)(id))cb {
NSString *eventId = [NSString stringWithFormat:@"%p-%@", self, [event identification]];
- (ARTEventListener *)_on:(nullable id<ARTEventIdentification>)event callback:(void (^)(id))cb {
NSString *eventId = event == nil ? [NSString stringWithFormat:@"%p", self] :
[NSString stringWithFormat:@"%p-%@", self, [event identification]];
__block ARTEventListener *listener;
id<NSObject> observer = [_notificationCenter addObserverForName:eventId object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
if (listener == nil || [listener invalidated]) return;
Expand All @@ -186,56 +187,42 @@ - (ARTEventListener *)on:(id<ARTEventIdentification>)event callback:(void (^)(id
cb(note.object);
}];
listener = [[ARTEventListener alloc] initWithId:eventId observer:observer handler:self center:_notificationCenter];
[self addObject:listener toArrayWithKey:listener.eventId inDictionary:self.listeners];
[self addObject:listener toArrayWithKey:event == nil ? nil : eventId];
return listener;
}

- (ARTEventListener *)once:(id<ARTEventIdentification>)event callback:(void (^)(id))cb {
NSString *eventId = [NSString stringWithFormat:@"%p-%@", self, [event identification]];
- (ARTEventListener *)on:(id<ARTEventIdentification>)event callback:(void (^)(id))cb {
return [self _on:event callback:cb];
}

- (ARTEventListener *)_once:(nullable id<ARTEventIdentification>)event callback:(void (^)(id))cb {
NSString *eventId = event == nil ? [NSString stringWithFormat:@"%p", self] :
[NSString stringWithFormat:@"%p-%@", self, [event identification]];
__block ARTEventListener *listener;
__weak typeof(self) weakSelf = self; // weak to avoid a warning, but strong should be safe too since the cycle is broken when the notification fires or the observer is cancelled
id<NSObject> observer = [_notificationCenter addObserverForName:eventId object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
if (listener == nil || [listener invalidated]) return;
if ([listener hasTimer] && ![listener timerIsRunning]) return;
if ([listener handled]) return;
[listener removeObserver];
[weakSelf removeObject:listener fromArrayWithKey:[listener eventId] inDictionary:[weakSelf listeners]];
[weakSelf removeObject:listener fromArrayWithKey:event == nil ? nil : eventId];
cb(note.object);
}];
listener = [[ARTEventListener alloc] initWithId:eventId observer:observer handler:self center:_notificationCenter];
[self addObject:listener toArrayWithKey:listener.eventId inDictionary:self.listeners];
[self addObject:listener toArrayWithKey:event == nil ? nil : eventId];
return listener;
}

- (ARTEventListener *)once:(id<ARTEventIdentification>)event callback:(void (^)(id))cb {
return [self _once:event callback:cb];
}

- (ARTEventListener *)on:(void (^)(id))cb {
NSString *eventId = [NSString stringWithFormat:@"%p", self];
__block ARTEventListener *listener;
id<NSObject> observer = [_notificationCenter addObserverForName:eventId object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
if (listener == nil || [listener invalidated]) return;
if ([listener hasTimer] && ![listener timerIsRunning]) return;
[listener stopTimer];
cb(note.object);
}];
listener = [[ARTEventListener alloc] initWithId:eventId observer:observer handler:self center:_notificationCenter];
[self.anyListeners addObject:listener];
return listener;
return [self _on:nil callback:cb];
}

- (ARTEventListener *)once:(void (^)(id))cb {
NSString *eventId = [NSString stringWithFormat:@"%p", self];
__block ARTEventListener *listener;
__weak typeof(self) weakSelf = self; // weak to avoid a warning, but strong should be safe too since the cycle is broken when the notification fires or the observer is cancelled
id<NSObject> observer = [_notificationCenter addObserverForName:eventId object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
if (listener == nil || [listener invalidated]) return;
if ([listener hasTimer] && ![listener timerIsRunning]) return;
if ([listener handled]) return;
[listener removeObserver];
[[weakSelf anyListeners] removeObject:listener];
cb(note.object);
}];
listener = [[ARTEventListener alloc] initWithId:eventId observer:observer handler:self center:_notificationCenter];
[self.anyListeners addObject:listener];
return listener;
return [self _once:nil callback:cb];
}

- (void)off:(id<ARTEventIdentification>)event listener:(ARTEventListener *)listener {
Expand Down Expand Up @@ -281,37 +268,44 @@ - (void)emit:(id<ARTEventIdentification>)event with:(id)data {
[self.notificationCenter postNotificationName:[NSString stringWithFormat:@"%p", self] object:data];
}

- (void)addObject:(id)obj toArrayWithKey:(id)key inDictionary:(NSMutableDictionary *)dict {
NSMutableArray *array = [dict objectForKey:key];
if (array == nil) {
array = [[NSMutableArray alloc] init];
[dict setObject:array forKey:key];
- (void)addObject:(id)obj toArrayWithKey:(nullable id)key {
if (key == nil) {
[_anyListeners addObject:obj];
}
if ([array indexOfObject:obj] == NSNotFound) {
[array addObject:obj];
else {
NSMutableArray *array = [_listeners objectForKey:key];
if (array == nil) {
array = [[NSMutableArray alloc] init];
[_listeners setObject:array forKey:key];
}
if ([array indexOfObject:obj] == NSNotFound) {
[array addObject:obj];
}
}
}

- (void)removeObject:(id)obj fromArrayWithKey:(id)key inDictionary:(NSMutableDictionary *)dict {
NSMutableArray *array = [dict objectForKey:key];
if (array == nil) {
return;
- (void)removeObject:(id)obj fromArrayWithKey:(nullable id)key where:(nullable BOOL(^)(id))cond {
if (key == nil) {
[_anyListeners removeObject:obj];
}
[array removeObject:obj];
if ([array count] == 0) {
[dict removeObjectForKey:key];
else {
NSMutableArray *array = [_listeners objectForKey:key];
if (array == nil) {
return;
}
if (cond) {
[array artRemoveWhere:cond];
} else {
[array removeObject:obj];
}
if ([array count] == 0) {
[_listeners removeObjectForKey:key];
}
}
}

- (void)removeObject:(id)obj fromArrayWithKey:(id)key inDictionary:(NSMutableDictionary *)dict where:(BOOL(^)(id))cond {
NSMutableArray *array = [dict objectForKey:key];
if (array == nil) {
return;
}
[array artRemoveWhere:cond];
if ([array count] == 0) {
[dict removeObjectForKey:key];
}
- (void)removeObject:(id)obj fromArrayWithKey:(id)key {
[self removeObject:obj fromArrayWithKey:key where:nil];
}

@end
Expand Down
2 changes: 2 additions & 0 deletions Source/ARTPresenceMessage.m
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ - (NSUInteger)hash {
return @"Leave"; //3
case ARTPresenceUpdate:
return @"Update"; //4
default:
return @"All";
}
}

Expand Down
10 changes: 3 additions & 7 deletions Source/ARTProtocolMessage.m
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,12 @@ - (id)copyWithZone:(NSZone *)zone {
return pm;
}

- (BOOL)mergeFrom:(ARTProtocolMessage *)src {
- (BOOL)mergeFrom:(ARTProtocolMessage *)src maxSize:(NSInteger)maxSize {
if (![src.channel isEqualToString:self.channel] || src.action != self.action) {
// RTL6d3
return NO;
}
if ([self mergeWouldExceedMaxSize:src.messages]) {
if ([self mergeWithMessages:src.messages wouldExceedMaxSize:maxSize]) {
// RTL6d1
return NO;
}
Expand Down Expand Up @@ -142,7 +142,7 @@ - (BOOL)clientIdsAreDifferent:(NSArray<ARTMessage*>*)messages {
}
}

- (BOOL)mergeWouldExceedMaxSize:(NSArray<ARTMessage*>*)messages {
- (BOOL)mergeWithMessages:(NSArray<ARTMessage*>*)messages wouldExceedMaxSize:(NSInteger)maxSize {
NSInteger queuedMessagesSize = 0;
for (ARTMessage *message in self.messages) {
queuedMessagesSize += [message messageSize];
Expand All @@ -152,10 +152,6 @@ - (BOOL)mergeWouldExceedMaxSize:(NSArray<ARTMessage*>*)messages {
messagesSize += [message messageSize];
}
NSInteger totalSize = queuedMessagesSize + messagesSize;
NSInteger maxSize = [ARTDefault maxMessageSize];
if (_connectionDetails.maxMessageSize) {
maxSize = _connectionDetails.maxMessageSize;
}
return totalSize > maxSize;
}

Expand Down
3 changes: 3 additions & 0 deletions Source/ARTPushActivationState.m
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,9 @@ - (ARTPushActivationState *)transition:(ARTPushActivationEvent *)event {
else if ([event isKindOfClass:[ARTPushActivationEventCalledActivate class]]) {
return validateAndSync(self.machine, event, self.logger);
}
else if ([event isKindOfClass:[ARTPushActivationEventGotPushDeviceDetails class]]) {
return self; // Consuming event (RSH3a3a)
}
return nil;
}

Expand Down
Loading

0 comments on commit 0d9af76

Please sign in to comment.