From a196bfe7710c7f2aaa377bd4228c365eb46d844c Mon Sep 17 00:00:00 2001 From: Lawrence Forooghian Date: Wed, 12 Feb 2025 13:01:11 -0300 Subject: [PATCH 01/16] Insert wrapper SDK agents in -time As in b006650. --- Source/ARTAuth.m | 3 +- Source/ARTRealtime.m | 9 ++-- Source/ARTRest.m | 14 +++--- Source/ARTWrapperSDKProxyRealtime.m | 3 +- .../PrivateHeaders/Ably/ARTRealtime+Private.h | 3 +- Source/PrivateHeaders/Ably/ARTRest+Private.h | 6 ++- Test/Tests/AuthTests.swift | 16 +++---- Test/Tests/WrapperSDKProxyTests.swift | 45 +++++++++++++++++++ 8 files changed, 78 insertions(+), 21 deletions(-) diff --git a/Source/ARTAuth.m b/Source/ARTAuth.m index 3252cf917..934c66035 100644 --- a/Source/ARTAuth.m +++ b/Source/ARTAuth.m @@ -708,7 +708,8 @@ - (void)createTokenRequest:(ARTTokenParams *)tokenParams options:(ARTAuthOptions } else { if (replacedOptions.queryTime) { - return [_rest _time:^(NSDate *time, NSError *error) { + return [_rest _timeWithWrapperSDKAgents:nil + completion:^(NSDate *time, NSError *error) { if (error) { callback(nil, error); } else { diff --git a/Source/ARTRealtime.m b/Source/ARTRealtime.m index 078630c36..5abddaff1 100644 --- a/Source/ARTRealtime.m +++ b/Source/ARTRealtime.m @@ -150,7 +150,8 @@ + (instancetype)createWithToken:(NSString *)tokenId { } - (void)time:(ARTDateTimeCallback)cb { - [_internal time:cb]; + [_internal timeWithWrapperSDKAgents:nil + completion:cb]; } - (BOOL)request:(NSString *)method @@ -501,8 +502,10 @@ - (void)_close { } } -- (void)time:(ARTDateTimeCallback)cb { - [self.rest time:cb]; +- (void)timeWithWrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents + completion:(ARTDateTimeCallback)cb { + [self.rest timeWithWrapperSDKAgents:wrapperSDKAgents + completion:cb]; } - (BOOL)request:(NSString *)method diff --git a/Source/ARTRest.m b/Source/ARTRest.m index bf2c4cc37..f94cb8430 100644 --- a/Source/ARTRest.m +++ b/Source/ARTRest.m @@ -102,7 +102,8 @@ + (instancetype)createWithToken:(NSString *)tokenId { } - (void)time:(ARTDateTimeCallback)callback { - [_internal time:callback]; + [_internal timeWithWrapperSDKAgents:nil + completion:callback]; } - (BOOL)request:(NSString *)method @@ -525,7 +526,8 @@ - (NSString *)prepareTokenAuthorisationHeader:(NSString *)token { return [NSString stringWithFormat:@"Bearer %@", token]; } -- (void)time:(ARTDateTimeCallback)callback { +- (void)timeWithWrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents + completion:(ARTDateTimeCallback)callback { if (callback) { ARTDateTimeCallback userCallback = callback; callback = ^(NSDate *time, NSError *error) { @@ -535,18 +537,20 @@ - (void)time:(ARTDateTimeCallback)callback { }; } dispatch_async(_queue, ^{ - [self _time:callback]; + [self _timeWithWrapperSDKAgents:wrapperSDKAgents + completion:callback]; }); } -- (NSObject *)_time:(ARTDateTimeCallback)callback { +- (NSObject *)_timeWithWrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents + completion:(ARTDateTimeCallback)callback { NSURL *requestUrl = [NSURL URLWithString:@"/time" relativeToURL:self.baseUrl]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:requestUrl]; request.HTTPMethod = @"GET"; NSString *accept = [[_encoders.allValues valueForKeyPath:@"mimeType"] componentsJoinedByString:@","]; [request setValue:accept forHTTPHeaderField:@"Accept"]; - return [self executeRequest:request withAuthOption:ARTAuthenticationOff wrapperSDKAgents:nil completion:^(NSHTTPURLResponse *response, NSData *data, NSError *error) { + return [self executeRequest:request withAuthOption:ARTAuthenticationOff wrapperSDKAgents:wrapperSDKAgents completion:^(NSHTTPURLResponse *response, NSData *data, NSError *error) { if (error) { callback(nil, error); return; diff --git a/Source/ARTWrapperSDKProxyRealtime.m b/Source/ARTWrapperSDKProxyRealtime.m index 46d1193a9..d465b8b49 100644 --- a/Source/ARTWrapperSDKProxyRealtime.m +++ b/Source/ARTWrapperSDKProxyRealtime.m @@ -90,7 +90,8 @@ - (BOOL)stats:(nullable ARTStatsQuery *)query callback:(nonnull ARTPaginatedStat } - (void)time:(nonnull ARTDateTimeCallback)callback { - [self.underlyingRealtime time:callback]; + [self.underlyingRealtime.internal timeWithWrapperSDKAgents:self.proxyOptions.agents + completion:callback]; } @end diff --git a/Source/PrivateHeaders/Ably/ARTRealtime+Private.h b/Source/PrivateHeaders/Ably/ARTRealtime+Private.h index 3ca64e274..3aaea8bcf 100644 --- a/Source/PrivateHeaders/Ably/ARTRealtime+Private.h +++ b/Source/PrivateHeaders/Ably/ARTRealtime+Private.h @@ -45,7 +45,8 @@ NS_ASSUME_NONNULL_BEGIN @property (readonly, nonatomic) dispatch_queue_t queue; -- (void)time:(ARTDateTimeCallback)callback; +- (void)timeWithWrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents + completion:(ARTDateTimeCallback)callback; - (BOOL)request:(NSString *)method path:(NSString *)path diff --git a/Source/PrivateHeaders/Ably/ARTRest+Private.h b/Source/PrivateHeaders/Ably/ARTRest+Private.h index 6e71c754d..a149382f4 100644 --- a/Source/PrivateHeaders/Ably/ARTRest+Private.h +++ b/Source/PrivateHeaders/Ably/ARTRest+Private.h @@ -66,7 +66,8 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)initWithOptions:(ARTClientOptions *)options realtime:(ARTRealtimeInternal *_Nullable)realtime logger:(ARTInternalLog *)logger; -- (nullable NSObject *)_time:(ARTDateTimeCallback)callback; +- (nullable NSObject *)_timeWithWrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents + completion:(ARTDateTimeCallback)callback; // MARK: ARTHTTPExecutor @@ -93,7 +94,8 @@ NS_ASSUME_NONNULL_BEGIN - (void)setAndPersistAPNSDeviceTokenData:(NSData *)deviceTokenData tokenType:(NSString *)tokenType; #endif -- (void)time:(ARTDateTimeCallback)callback; +- (void)timeWithWrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents + completion:(ARTDateTimeCallback)callback; - (BOOL)request:(NSString *)method path:(NSString *)path diff --git a/Test/Tests/AuthTests.swift b/Test/Tests/AuthTests.swift index 17d614cc2..a5a9cd7ca 100644 --- a/Test/Tests/AuthTests.swift +++ b/Test/Tests/AuthTests.swift @@ -2027,7 +2027,7 @@ class AuthTests: XCTestCase { rest.auth.internal.testSuite_returnValue(for: NSSelectorFromString("handleServerTime:"), with: mockServerDate) var serverTimeRequestCount = 0 - let hook = rest.internal.testSuite_injectIntoMethod(after: #selector(rest.internal._time(_:))) { + let hook = rest.internal.testSuite_injectIntoMethod(after: #selector(rest.internal._time(withWrapperSDKAgents:completion:))) { serverTimeRequestCount += 1 } defer { hook.remove() } @@ -2171,7 +2171,7 @@ class AuthTests: XCTestCase { authOptions.key = options.key var serverTimeRequestCount = 0 - let hook = rest.internal.testSuite_injectIntoMethod(after: #selector(rest.internal._time(_:))) { + let hook = rest.internal.testSuite_injectIntoMethod(after: #selector(rest.internal._time(withWrapperSDKAgents:completion:))) { serverTimeRequestCount += 1 } defer { hook.remove() } @@ -2306,7 +2306,7 @@ class AuthTests: XCTestCase { let hook = ARTRestInternal.aspect_hook(rest.internal) // Adds a block of code after `time` is triggered - _ = try hook(#selector(ARTRestInternal._time(_:)), .positionBefore, unsafeBitCast(block, to: ARTRestInternal.self)) + _ = try hook(#selector(ARTRestInternal._time(withWrapperSDKAgents:completion:)), .positionBefore, unsafeBitCast(block, to: ARTRestInternal.self)) let authOptions = ARTAuthOptions() authOptions.queryTime = true @@ -2776,7 +2776,7 @@ class AuthTests: XCTestCase { authOptions.queryTime = true var serverTimeRequestWasMade = false - let hook = rest.internal.testSuite_injectIntoMethod(after: #selector(rest.internal._time(_:))) { + let hook = rest.internal.testSuite_injectIntoMethod(after: #selector(rest.internal._time(withWrapperSDKAgents:completion:))) { serverTimeRequestWasMade = true } defer { hook.remove() } @@ -3334,7 +3334,7 @@ class AuthTests: XCTestCase { authOptions.queryTime = true var serverTimeRequestCount = 0 - let hook = rest.internal.testSuite_injectIntoMethod(after: #selector(rest.internal._time(_:))) { + let hook = rest.internal.testSuite_injectIntoMethod(after: #selector(rest.internal._time(withWrapperSDKAgents:completion:))) { serverTimeRequestCount += 1 } defer { hook.remove() } @@ -3437,7 +3437,7 @@ class AuthTests: XCTestCase { let currentDate = Date() var serverTimeRequestCount = 0 - let hook = rest.internal.testSuite_injectIntoMethod(after: #selector(rest.internal._time(_:))) { + let hook = rest.internal.testSuite_injectIntoMethod(after: #selector(rest.internal._time(withWrapperSDKAgents:completion:))) { serverTimeRequestCount += 1 } defer { hook.remove() } @@ -3493,7 +3493,7 @@ class AuthTests: XCTestCase { rest.auth.internal.testSuite_returnValue(for: NSSelectorFromString("handleServerTime:"), with: mockServerDate) var serverTimeRequestCount = 0 - let hook = rest.internal.testSuite_injectIntoMethod(after: #selector(rest.internal._time(_:))) { + let hook = rest.internal.testSuite_injectIntoMethod(after: #selector(rest.internal._time(withWrapperSDKAgents:completion:))) { serverTimeRequestCount += 1 } defer { hook.remove() } @@ -3527,7 +3527,7 @@ class AuthTests: XCTestCase { let rest = ARTRest(options: options) var serverTimeRequestCount = 0 - let hook = rest.internal.testSuite_injectIntoMethod(after: #selector(rest.internal._time(_:))) { + let hook = rest.internal.testSuite_injectIntoMethod(after: #selector(rest.internal._time(withWrapperSDKAgents:completion:))) { serverTimeRequestCount += 1 } defer { hook.remove() } diff --git a/Test/Tests/WrapperSDKProxyTests.swift b/Test/Tests/WrapperSDKProxyTests.swift index f34f41b3b..0291f70f7 100644 --- a/Test/Tests/WrapperSDKProxyTests.swift +++ b/Test/Tests/WrapperSDKProxyTests.swift @@ -319,6 +319,51 @@ class WrapperSDKProxyTests: XCTestCase { } } + func parameterizedTest_addsWrapperSDKAgentToRequests( + test: Test, + performRequest: @escaping (ARTWrapperSDKProxyRealtime) -> Void + ) throws { + // Given: a wrapper SDK proxy client + + let options = try AblyTests.commonAppSetup(for: test) + let realtime = ARTRealtime(options: options) + defer { realtime.dispose(); realtime.close() } + + let testHTTPExecutor = TestProxyHTTPExecutor(logger: .init(clientOptions: options)) + realtime.internal.rest.httpExecutor = testHTTPExecutor + + let proxyClient = realtime.createWrapperSDKProxy(with: .init(agents: ["my-wrapper-sdk": "1.0.0"])) + + // When: We perform an HTTP request via the wrapper proxy SDK client + performRequest(proxyClient) + + // Then: The HTTP request all contains the wrapper SDK's agents in the Ably-Agent header + XCTAssertEqual(testHTTPExecutor.requests.count, 1) + + let expectedIdentifier = [ + "ably-cocoa/1.2.38", + ARTDefault.platformAgent(), + "my-wrapper-sdk/1.0.0" + ].sorted().joined(separator: " ") + + let request = try XCTUnwrap(testHTTPExecutor.requests.first) + + XCTAssertEqual(request.allHTTPHeaderFields?["Ably-Agent"], expectedIdentifier) + } + + func test_time_addsWrapperSDKAgentToRequest() throws { + let test = Test() + + try parameterizedTest_addsWrapperSDKAgentToRequests(test: test) { proxyClient in + waitUntil(timeout: testTimeout) { done in + proxyClient.time() { _, error in + XCTAssertNil(error) + done() + } + } + } + } + // MARK: - `agent` channel param private func parameterizedTest_checkAttachProtocolMessage( From e56cfbf205fc4a27aa3ff334da21a6813c154cf4 Mon Sep 17 00:00:00 2001 From: Lawrence Forooghian Date: Wed, 12 Feb 2025 13:39:04 -0300 Subject: [PATCH 02/16] Move wrapperSDKAgents into ARTPaginatedResult Preparation for extending b006650 and 9071d8f to other REST requests. --- Source/ARTHTTPPaginatedResponse.m | 3 +-- Source/ARTPaginatedResult.m | 11 +++++++---- Source/ARTPushChannel.m | 2 +- Source/ARTPushChannelSubscriptions.m | 4 ++-- Source/ARTPushDeviceRegistrations.m | 2 +- Source/ARTRest.m | 2 +- Source/ARTRestChannel.m | 2 +- Source/ARTRestPresence.m | 4 ++-- .../Ably/ARTHTTPPaginatedResponse+Private.h | 1 - .../PrivateHeaders/Ably/ARTPaginatedResult+Private.h | 2 ++ .../PrivateHeaders/Ably/ARTPaginatedResult+Subclass.h | 1 + 11 files changed, 19 insertions(+), 15 deletions(-) diff --git a/Source/ARTHTTPPaginatedResponse.m b/Source/ARTHTTPPaginatedResponse.m index 3944798ac..db07d0b42 100644 --- a/Source/ARTHTTPPaginatedResponse.m +++ b/Source/ARTHTTPPaginatedResponse.m @@ -22,10 +22,9 @@ - (instancetype)initWithResponse:(NSHTTPURLResponse *)response responseProcessor:(ARTPaginatedResultResponseProcessor)responseProcessor wrapperSDKAgents:(nullable NSDictionary *)wrapperSDKAgents logger:(ARTInternalLog *)logger { - self = [super initWithItems:items rest:rest relFirst:relFirst relCurrent:relCurrent relNext:relNext responseProcessor:responseProcessor logger:logger]; + self = [super initWithItems:items rest:rest relFirst:relFirst relCurrent:relCurrent relNext:relNext responseProcessor:responseProcessor wrapperSDKAgents:wrapperSDKAgents logger:logger]; if (self) { _response = response; - _wrapperSDKAgents = [wrapperSDKAgents copy]; } return self; } diff --git a/Source/ARTPaginatedResult.m b/Source/ARTPaginatedResult.m index 659cc9ad6..88992ad04 100644 --- a/Source/ARTPaginatedResult.m +++ b/Source/ARTPaginatedResult.m @@ -46,6 +46,7 @@ - (instancetype)initWithItems:(NSArray *)items relCurrent:(NSMutableURLRequest *)relCurrent relNext:(NSMutableURLRequest *)relNext responseProcessor:(ARTPaginatedResultResponseProcessor)responseProcessor + wrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents logger:(ARTInternalLog *)logger { if (self = [super init]) { _initializedViaInit = NO; @@ -64,6 +65,7 @@ - (instancetype)initWithItems:(NSArray *)items _userQueue = rest.userQueue; _queue = rest.queue; _responseProcessor = responseProcessor; + _wrapperSDKAgents = wrapperSDKAgents; _logger = logger; // ARTPaginatedResult doesn't need a internal counterpart, as other @@ -116,7 +118,7 @@ - (void)first:(void (^)(ARTPaginatedResult *_Nullable result, ARTErrorInfo * }; } - [self.class executePaginated:_rest withRequest:_relFirst andResponseProcessor:_responseProcessor logger:_logger callback:callback]; + [self.class executePaginated:_rest withRequest:_relFirst andResponseProcessor:_responseProcessor wrapperSDKAgents:_wrapperSDKAgents logger:_logger callback:callback]; } - (void)next:(void (^)(ARTPaginatedResult *_Nullable result, ARTErrorInfo *_Nullable error))callback { @@ -138,13 +140,13 @@ - (void)next:(void (^)(ARTPaginatedResult *_Nullable result, ARTErrorInfo *_ callback(nil, nil); return; } - [self.class executePaginated:_rest withRequest:_relNext andResponseProcessor:_responseProcessor logger:_logger callback:callback]; + [self.class executePaginated:_rest withRequest:_relNext andResponseProcessor:_responseProcessor wrapperSDKAgents:_wrapperSDKAgents logger:_logger callback:callback]; } -+ (void)executePaginated:(ARTRestInternal *)rest withRequest:(NSMutableURLRequest *)request andResponseProcessor:(ARTPaginatedResultResponseProcessor)responseProcessor logger:(ARTInternalLog *)logger callback:(void (^)(ARTPaginatedResult *_Nullable result, ARTErrorInfo *_Nullable error))callback { ++ (void)executePaginated:(ARTRestInternal *)rest withRequest:(NSMutableURLRequest *)request andResponseProcessor:(ARTPaginatedResultResponseProcessor)responseProcessor wrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents logger:(ARTInternalLog *)logger callback:(void (^)(ARTPaginatedResult *_Nullable result, ARTErrorInfo *_Nullable error))callback { ARTLogDebug(logger, @"Paginated request: %@", request); - [rest executeRequest:request withAuthOption:ARTAuthenticationOn wrapperSDKAgents:nil completion:^(NSHTTPURLResponse *response, NSData *data, NSError *error) { + [rest executeRequest:request withAuthOption:ARTAuthenticationOn wrapperSDKAgents:wrapperSDKAgents completion:^(NSHTTPURLResponse *response, NSData *data, NSError *error) { if (error) { callback(nil, [ARTErrorInfo createFromNSError:error]); } else { @@ -171,6 +173,7 @@ + (void)executePaginated:(ARTRestInternal *)rest withRequest:(NSMutableURLReques relCurrent:currentRel relNext:nextRel responseProcessor:responseProcessor + wrapperSDKAgents:wrapperSDKAgents logger:logger]; callback(result, nil); diff --git a/Source/ARTPushChannel.m b/Source/ARTPushChannel.m index f216698e6..57c8207d3 100644 --- a/Source/ARTPushChannel.m +++ b/Source/ARTPushChannel.m @@ -290,7 +290,7 @@ - (BOOL)listSubscriptions:(NSStringDictionary *)params return [self->_rest.encoders[response.MIMEType] decodePushChannelSubscriptions:data error:error]; }; - [ARTPaginatedResult executePaginated:self->_rest withRequest:request andResponseProcessor:responseProcessor logger:self->_logger callback:callback]; + [ARTPaginatedResult executePaginated:self->_rest withRequest:request andResponseProcessor:responseProcessor wrapperSDKAgents:nil logger:self->_logger callback:callback]; ret = YES; }); return ret; diff --git a/Source/ARTPushChannelSubscriptions.m b/Source/ARTPushChannelSubscriptions.m index f9370d9e0..a121135a8 100644 --- a/Source/ARTPushChannelSubscriptions.m +++ b/Source/ARTPushChannelSubscriptions.m @@ -126,7 +126,7 @@ - (void)listChannels:(ARTPaginatedTextCallback)callback { ARTPaginatedResultResponseProcessor responseProcessor = ^(NSHTTPURLResponse *response, NSData *data, NSError **error) { return [self->_rest.encoders[response.MIMEType] decode:data error:error]; }; - [ARTPaginatedResult executePaginated:self->_rest withRequest:request andResponseProcessor:responseProcessor logger:self->_logger callback:callback]; + [ARTPaginatedResult executePaginated:self->_rest withRequest:request andResponseProcessor:responseProcessor wrapperSDKAgents:nil logger:self->_logger callback:callback]; }); } @@ -149,7 +149,7 @@ - (void)list:(NSStringDictionary *)params callback:(ARTPaginatedPushChannelCallb ARTPaginatedResultResponseProcessor responseProcessor = ^(NSHTTPURLResponse *response, NSData *data, NSError **error) { return [self->_rest.encoders[response.MIMEType] decodePushChannelSubscriptions:data error:error]; }; - [ARTPaginatedResult executePaginated:self->_rest withRequest:request andResponseProcessor:responseProcessor logger:self->_logger callback:callback]; + [ARTPaginatedResult executePaginated:self->_rest withRequest:request andResponseProcessor:responseProcessor wrapperSDKAgents:nil logger:self->_logger callback:callback]; }); } diff --git a/Source/ARTPushDeviceRegistrations.m b/Source/ARTPushDeviceRegistrations.m index f08bb2dbe..493783061 100644 --- a/Source/ARTPushDeviceRegistrations.m +++ b/Source/ARTPushDeviceRegistrations.m @@ -188,7 +188,7 @@ - (void)list:(NSStringDictionary *)params callback:(ARTPaginatedDeviceDetailsCal ARTPaginatedResultResponseProcessor responseProcessor = ^(NSHTTPURLResponse *response, NSData *data, NSError **error) { return [self->_rest.encoders[response.MIMEType] decodeDevicesDetails:data error:error]; }; - [ARTPaginatedResult executePaginated:self->_rest withRequest:request andResponseProcessor:responseProcessor logger:self->_logger callback:callback]; + [ARTPaginatedResult executePaginated:self->_rest withRequest:request andResponseProcessor:responseProcessor wrapperSDKAgents:nil logger:self->_logger callback:callback]; }); } diff --git a/Source/ARTRest.m b/Source/ARTRest.m index f94cb8430..2b84f1149 100644 --- a/Source/ARTRest.m +++ b/Source/ARTRest.m @@ -727,7 +727,7 @@ - (BOOL)stats:(ARTStatsQuery *)query callback:(ARTPaginatedStatsCallback)callbac }; dispatch_async(_queue, ^{ - [ARTPaginatedResult executePaginated:self withRequest:request andResponseProcessor:responseProcessor logger:self.logger callback:callback]; + [ARTPaginatedResult executePaginated:self withRequest:request andResponseProcessor:responseProcessor wrapperSDKAgents:nil logger:self.logger callback:callback]; }); return YES; } diff --git a/Source/ARTRestChannel.m b/Source/ARTRestChannel.m index 2b01895cc..d1a10fb3b 100644 --- a/Source/ARTRestChannel.m +++ b/Source/ARTRestChannel.m @@ -210,7 +210,7 @@ - (BOOL)history:(ARTDataQuery *)query callback:(ARTPaginatedMessagesCallback)cal }; ARTLogDebug(self.logger, @"RS:%p C:%p (%@) stats request %@", self->_rest, self, self.name, request); - [ARTPaginatedResult executePaginated:self->_rest withRequest:request andResponseProcessor:responseProcessor logger:self.logger callback:callback]; + [ARTPaginatedResult executePaginated:self->_rest withRequest:request andResponseProcessor:responseProcessor wrapperSDKAgents:nil logger:self.logger callback:callback]; ret = YES; }); return ret; diff --git a/Source/ARTRestPresence.m b/Source/ARTRestPresence.m index 7bac83682..e113764b5 100644 --- a/Source/ARTRestPresence.m +++ b/Source/ARTRestPresence.m @@ -156,7 +156,7 @@ - (BOOL)get:(ARTPresenceQuery *)query callback:(ARTPaginatedPresenceCallback)cal }; dispatch_async(_queue, ^{ - [ARTPaginatedResult executePaginated:self->_channel.rest withRequest:request andResponseProcessor:responseProcessor logger:self->_logger callback:callback]; + [ARTPaginatedResult executePaginated:self->_channel.rest withRequest:request andResponseProcessor:responseProcessor wrapperSDKAgents:nil logger:self->_logger callback:callback]; }); return YES; } @@ -217,7 +217,7 @@ - (BOOL)history:(ARTDataQuery *)query callback:(ARTPaginatedPresenceCallback)cal }; dispatch_async(_queue, ^{ - [ARTPaginatedResult executePaginated:self->_channel.rest withRequest:request andResponseProcessor:responseProcessor logger:self->_logger callback:callback]; + [ARTPaginatedResult executePaginated:self->_channel.rest withRequest:request andResponseProcessor:responseProcessor wrapperSDKAgents:nil logger:self->_logger callback:callback]; }); return YES; } diff --git a/Source/PrivateHeaders/Ably/ARTHTTPPaginatedResponse+Private.h b/Source/PrivateHeaders/Ably/ARTHTTPPaginatedResponse+Private.h index c752acbea..73a164aab 100644 --- a/Source/PrivateHeaders/Ably/ARTHTTPPaginatedResponse+Private.h +++ b/Source/PrivateHeaders/Ably/ARTHTTPPaginatedResponse+Private.h @@ -9,7 +9,6 @@ NS_ASSUME_NONNULL_BEGIN @interface ARTHTTPPaginatedResponse () @property (nonatomic) NSHTTPURLResponse *response; -@property (nullable, nonatomic, readonly) NSDictionary *wrapperSDKAgents; - (instancetype)initWithResponse:(NSHTTPURLResponse *)response items:(NSArray *)items diff --git a/Source/PrivateHeaders/Ably/ARTPaginatedResult+Private.h b/Source/PrivateHeaders/Ably/ARTPaginatedResult+Private.h index ea7300cfa..ddac3a779 100644 --- a/Source/PrivateHeaders/Ably/ARTPaginatedResult+Private.h +++ b/Source/PrivateHeaders/Ably/ARTPaginatedResult+Private.h @@ -22,11 +22,13 @@ typedef NSArray *_Nullable(^ARTPaginatedResultResponseProcessor)(NSHTT relCurrent:(NSMutableURLRequest *)relCurrent relNext:(NSMutableURLRequest *)relNext responseProcessor:(ARTPaginatedResultResponseProcessor)responseProcessor + wrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents logger:(ARTInternalLog *)logger NS_DESIGNATED_INITIALIZER; + (void)executePaginated:(ARTRestInternal *)rest withRequest:(NSMutableURLRequest *)request andResponseProcessor:(ARTPaginatedResultResponseProcessor)responseProcessor + wrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents logger:(ARTInternalLog *)logger callback:(void (^)(ARTPaginatedResult *_Nullable result, ARTErrorInfo *_Nullable error))callback; diff --git a/Source/PrivateHeaders/Ably/ARTPaginatedResult+Subclass.h b/Source/PrivateHeaders/Ably/ARTPaginatedResult+Subclass.h index 1cedb9432..d9fe2815b 100644 --- a/Source/PrivateHeaders/Ably/ARTPaginatedResult+Subclass.h +++ b/Source/PrivateHeaders/Ably/ARTPaginatedResult+Subclass.h @@ -5,6 +5,7 @@ NS_ASSUME_NONNULL_BEGIN @interface ARTPaginatedResult () +@property (nullable, nonatomic, readonly) NSStringDictionary *wrapperSDKAgents; @property (nonatomic, readonly) ARTInternalLog *logger; @end From abd30c910856b4d45fd68b3dc84deec94b02fc9a Mon Sep 17 00:00:00 2001 From: Lawrence Forooghian Date: Thu, 13 Feb 2025 11:56:47 -0300 Subject: [PATCH 03/16] Make ARTChannel class private It's an implementation detail; the public API doesn't refer to it. --- Ably.xcodeproj/project.pbxproj | 16 +++++++++--- Source/ARTChannelProtocol.m | 0 Source/Ably.modulemap | 1 + Source/PrivateHeaders/Ably/ARTChannel.h | 26 +++++++++++++++++++ .../Ably/ARTPushChannel+Private.h | 1 + .../Ably/ARTRealtimeChannel+Private.h | 1 + .../Ably/ARTRestChannel+Private.h | 1 + Source/include/Ably.modulemap | 1 + .../{ARTChannel.h => ARTChannelProtocol.h} | 12 +-------- Source/include/Ably/ARTPushChannel.h | 1 - Source/include/Ably/ARTRestChannel.h | 2 +- Source/include/Ably/AblyPublic.h | 1 + 12 files changed, 46 insertions(+), 17 deletions(-) create mode 100644 Source/ARTChannelProtocol.m create mode 100644 Source/PrivateHeaders/Ably/ARTChannel.h rename Source/include/Ably/{ARTChannel.h => ARTChannelProtocol.h} (84%) diff --git a/Ably.xcodeproj/project.pbxproj b/Ably.xcodeproj/project.pbxproj index d52df1be6..099e0c2aa 100644 --- a/Ably.xcodeproj/project.pbxproj +++ b/Ably.xcodeproj/project.pbxproj @@ -320,6 +320,9 @@ 21E1C0E92A0DC5E600A5DB65 /* ARTWebSocketFactory.m in Sources */ = {isa = PBXBuildFile; fileRef = 21E1C0E82A0DC5E600A5DB65 /* ARTWebSocketFactory.m */; }; 21E1C0EA2A0DC5E600A5DB65 /* ARTWebSocketFactory.m in Sources */ = {isa = PBXBuildFile; fileRef = 21E1C0E82A0DC5E600A5DB65 /* ARTWebSocketFactory.m */; }; 21E1C0EB2A0DC5E600A5DB65 /* ARTWebSocketFactory.m in Sources */ = {isa = PBXBuildFile; fileRef = 21E1C0E82A0DC5E600A5DB65 /* ARTWebSocketFactory.m */; }; + 21E5D87F2D5E3EC300526C4C /* ARTChannelProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 21E5D87E2D5E3EC300526C4C /* ARTChannelProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 21E5D8802D5E3EC300526C4C /* ARTChannelProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 21E5D87E2D5E3EC300526C4C /* ARTChannelProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 21E5D8812D5E3EC300526C4C /* ARTChannelProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 21E5D87E2D5E3EC300526C4C /* ARTChannelProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; }; 21FD9F272A015BE400216482 /* Test.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21FD9F262A015BE400216482 /* Test.swift */; }; 21FD9F282A015BE400216482 /* Test.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21FD9F262A015BE400216482 /* Test.swift */; }; 21FD9F292A015BE400216482 /* Test.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21FD9F262A015BE400216482 /* Test.swift */; }; @@ -694,7 +697,7 @@ D710D58221949D28008F54AD /* ARTTokenParams.h in Headers */ = {isa = PBXBuildFile; fileRef = D7D8F8291BC2C706009718F2 /* ARTTokenParams.h */; settings = {ATTRIBUTES = (Public, ); }; }; D710D58321949D28008F54AD /* ARTTokenDetails.h in Headers */ = {isa = PBXBuildFile; fileRef = D7D8F8231BC2C691009718F2 /* ARTTokenDetails.h */; settings = {ATTRIBUTES = (Public, ); }; }; D710D58421949D28008F54AD /* ARTClientOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 961343D61A42E0B7006DC822 /* ARTClientOptions.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D710D58521949D28008F54AD /* ARTChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = D746AE201BBB60EE003ECEF8 /* ARTChannel.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D710D58521949D28008F54AD /* ARTChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = D746AE201BBB60EE003ECEF8 /* ARTChannel.h */; settings = {ATTRIBUTES = (Private, ); }; }; D710D58621949D29008F54AD /* ARTChannels.h in Headers */ = {isa = PBXBuildFile; fileRef = D746AE511BBD85C5003ECEF8 /* ARTChannels.h */; settings = {ATTRIBUTES = (Public, ); }; }; D710D58721949D29008F54AD /* ARTChannelOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = D746AE4D1BBD84E7003ECEF8 /* ARTChannelOptions.h */; settings = {ATTRIBUTES = (Public, ); }; }; D710D58821949D29008F54AD /* ARTProtocolMessage.h in Headers */ = {isa = PBXBuildFile; fileRef = 96E408411A38939E00087F77 /* ARTProtocolMessage.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -712,7 +715,7 @@ D710D5A821949D2A008F54AD /* ARTTokenParams.h in Headers */ = {isa = PBXBuildFile; fileRef = D7D8F8291BC2C706009718F2 /* ARTTokenParams.h */; settings = {ATTRIBUTES = (Public, ); }; }; D710D5A921949D2A008F54AD /* ARTTokenDetails.h in Headers */ = {isa = PBXBuildFile; fileRef = D7D8F8231BC2C691009718F2 /* ARTTokenDetails.h */; settings = {ATTRIBUTES = (Public, ); }; }; D710D5AA21949D2A008F54AD /* ARTClientOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 961343D61A42E0B7006DC822 /* ARTClientOptions.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D710D5AB21949D2A008F54AD /* ARTChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = D746AE201BBB60EE003ECEF8 /* ARTChannel.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D710D5AB21949D2A008F54AD /* ARTChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = D746AE201BBB60EE003ECEF8 /* ARTChannel.h */; settings = {ATTRIBUTES = (Private, ); }; }; D710D5AC21949D2A008F54AD /* ARTChannels.h in Headers */ = {isa = PBXBuildFile; fileRef = D746AE511BBD85C5003ECEF8 /* ARTChannels.h */; settings = {ATTRIBUTES = (Public, ); }; }; D710D5AD21949D2A008F54AD /* ARTChannelOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = D746AE4D1BBD84E7003ECEF8 /* ARTChannelOptions.h */; settings = {ATTRIBUTES = (Public, ); }; }; D710D5AE21949D2A008F54AD /* ARTProtocolMessage.h in Headers */ = {isa = PBXBuildFile; fileRef = 96E408411A38939E00087F77 /* ARTProtocolMessage.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -902,7 +905,7 @@ D746AE1D1BBB5207003ECEF8 /* ARTDataQuery.h in Headers */ = {isa = PBXBuildFile; fileRef = D746AE1A1BBB5207003ECEF8 /* ARTDataQuery.h */; settings = {ATTRIBUTES = (Public, ); }; }; D746AE1E1BBB5207003ECEF8 /* ARTDataQuery+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = D746AE1B1BBB5207003ECEF8 /* ARTDataQuery+Private.h */; settings = {ATTRIBUTES = (Private, ); }; }; D746AE1F1BBB5207003ECEF8 /* ARTDataQuery.m in Sources */ = {isa = PBXBuildFile; fileRef = D746AE1C1BBB5207003ECEF8 /* ARTDataQuery.m */; }; - D746AE221BBB60EE003ECEF8 /* ARTChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = D746AE201BBB60EE003ECEF8 /* ARTChannel.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D746AE221BBB60EE003ECEF8 /* ARTChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = D746AE201BBB60EE003ECEF8 /* ARTChannel.h */; settings = {ATTRIBUTES = (Private, ); }; }; D746AE231BBB60EE003ECEF8 /* ARTChannel.m in Sources */ = {isa = PBXBuildFile; fileRef = D746AE211BBB60EE003ECEF8 /* ARTChannel.m */; }; D746AE251BBB611C003ECEF8 /* ARTChannel+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = D746AE241BBB611C003ECEF8 /* ARTChannel+Private.h */; settings = {ATTRIBUTES = (Private, ); }; }; D746AE281BBB61C9003ECEF8 /* ARTPresence.h in Headers */ = {isa = PBXBuildFile; fileRef = D746AE261BBB61C9003ECEF8 /* ARTPresence.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -1298,6 +1301,7 @@ 21DCDA8429F81B550073A211 /* Ably-tvOS.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = "Ably-tvOS.xctestplan"; sourceTree = ""; }; 21E1C0E42A0DC47400A5DB65 /* ARTWebSocketFactory.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ARTWebSocketFactory.h; path = PrivateHeaders/ARTWebSocketFactory.h; sourceTree = ""; }; 21E1C0E82A0DC5E600A5DB65 /* ARTWebSocketFactory.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ARTWebSocketFactory.m; sourceTree = ""; }; + 21E5D87E2D5E3EC300526C4C /* ARTChannelProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ARTChannelProtocol.h; path = include/Ably/ARTChannelProtocol.h; sourceTree = ""; }; 21FD9F262A015BE400216482 /* Test.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Test.swift; sourceTree = ""; }; 560579D824AF1BA900A4D03D /* ARTDefaultTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ARTDefaultTests.swift; sourceTree = ""; }; 56190953238C3D3200A862A6 /* CryptoTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CryptoTest.m; sourceTree = ""; }; @@ -1417,7 +1421,7 @@ D746AE1A1BBB5207003ECEF8 /* ARTDataQuery.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ARTDataQuery.h; path = include/Ably/ARTDataQuery.h; sourceTree = ""; }; D746AE1B1BBB5207003ECEF8 /* ARTDataQuery+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "ARTDataQuery+Private.h"; path = "PrivateHeaders/Ably/ARTDataQuery+Private.h"; sourceTree = ""; }; D746AE1C1BBB5207003ECEF8 /* ARTDataQuery.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARTDataQuery.m; sourceTree = ""; }; - D746AE201BBB60EE003ECEF8 /* ARTChannel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ARTChannel.h; path = include/Ably/ARTChannel.h; sourceTree = ""; }; + D746AE201BBB60EE003ECEF8 /* ARTChannel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ARTChannel.h; path = PrivateHeaders/Ably/ARTChannel.h; sourceTree = ""; }; D746AE211BBB60EE003ECEF8 /* ARTChannel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARTChannel.m; sourceTree = ""; }; D746AE241BBB611C003ECEF8 /* ARTChannel+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "ARTChannel+Private.h"; path = "PrivateHeaders/Ably/ARTChannel+Private.h"; sourceTree = ""; }; D746AE261BBB61C9003ECEF8 /* ARTPresence.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ARTPresence.h; path = include/Ably/ARTPresence.h; sourceTree = ""; }; @@ -2089,6 +2093,7 @@ 21113B5029DC6AAF00652C86 /* ARTTestClientOptions.h */, 21113B5429DC6ACD00652C86 /* ARTTestClientOptions.m */, 961343D71A42E0B7006DC822 /* ARTClientOptions.m */, + 21E5D87E2D5E3EC300526C4C /* ARTChannelProtocol.h */, D746AE201BBB60EE003ECEF8 /* ARTChannel.h */, D746AE241BBB611C003ECEF8 /* ARTChannel+Private.h */, 21113B4429DB484200652C86 /* ARTChannel+Subclass.h */, @@ -2411,6 +2416,7 @@ D7D06F0826330E2800DEBDAD /* ARTHttp+Private.h in Headers */, EB1B541922FB1D7F006A59AC /* ARTPushChannelSubscriptions+Private.h in Headers */, 2105ED1E29E7242400DE6D67 /* ARTLogAdapter+Testing.h in Headers */, + 21E5D8812D5E3EC300526C4C /* ARTChannelProtocol.h in Headers */, EBF2285B1F4D9AD6009091DD /* ARTWebSocketTransport+Private.h in Headers */, EBFFAC191E97919C003E7326 /* ARTLocalDevice+Private.h in Headers */, 211A60DB29D726F800D169C5 /* ARTConnectionStateChangeParams.h in Headers */, @@ -2616,6 +2622,7 @@ 2124B78C29DB12A900AD8361 /* ARTVersion2Log.h in Headers */, EB1B53FE22F8D91C006A59AC /* ARTQueuedDealloc.h in Headers */, 2114D4282D4BC5470032839A /* AblyInternal.h in Headers */, + 21E5D87F2D5E3EC300526C4C /* ARTChannelProtocol.h in Headers */, 2114D4292D4BC5470032839A /* AblyPublic.h in Headers */, D710D56A21949CB9008F54AD /* ARTPushAdmin.h in Headers */, D710D48321949A4E008F54AD /* ARTDefault+Private.h in Headers */, @@ -2796,6 +2803,7 @@ 2124B78D29DB12A900AD8361 /* ARTVersion2Log.h in Headers */, D710D47F21949A28008F54AD /* Ably.h in Headers */, 2114D42C2D4BC5470032839A /* AblyInternal.h in Headers */, + 21E5D8802D5E3EC300526C4C /* ARTChannelProtocol.h in Headers */, 2114D42D2D4BC5470032839A /* AblyPublic.h in Headers */, EB1B53FF22F8D91C006A59AC /* ARTQueuedDealloc.h in Headers */, D710D57021949CBA008F54AD /* ARTPushAdmin.h in Headers */, diff --git a/Source/ARTChannelProtocol.m b/Source/ARTChannelProtocol.m new file mode 100644 index 000000000..e69de29bb diff --git a/Source/Ably.modulemap b/Source/Ably.modulemap index 5123299a4..b59c570c7 100644 --- a/Source/Ably.modulemap +++ b/Source/Ably.modulemap @@ -115,5 +115,6 @@ framework module Ably { header "ARTWrapperSDKProxyRealtime+Private.h" header "ARTWrapperSDKProxyRealtimeChannels+Private.h" header "ARTWrapperSDKProxyRealtimeChannel+Private.h" + header "ARTChannel.h" } } diff --git a/Source/PrivateHeaders/Ably/ARTChannel.h b/Source/PrivateHeaders/Ably/ARTChannel.h new file mode 100644 index 000000000..82e3b267d --- /dev/null +++ b/Source/PrivateHeaders/Ably/ARTChannel.h @@ -0,0 +1,26 @@ +#import + +#import +#import + +@class ARTRest; +@class ARTChannelOptions; +@class ARTMessage; +@class ARTBaseMessage; +@class ARTPaginatedResult; +@class ARTDataQuery; +@class ARTLocalDevice; + +NS_ASSUME_NONNULL_BEGIN + +/** + * The base class for `ARTRestChannel` and `ARTRealtimeChannel`. + * Ably platform service organizes the message traffic within applications into named channels. Channels are the medium through which messages are distributed; clients attach to channels to subscribe to messages, and every message published to a unique channel is broadcast by Ably to all subscribers. + * + * @see See `ARTChannelProtocol` for details. + */ +NS_SWIFT_SENDABLE +@interface ARTChannel : NSObject +@end + +NS_ASSUME_NONNULL_END diff --git a/Source/PrivateHeaders/Ably/ARTPushChannel+Private.h b/Source/PrivateHeaders/Ably/ARTPushChannel+Private.h index 9f0f82f87..77e1d39c2 100644 --- a/Source/PrivateHeaders/Ably/ARTPushChannel+Private.h +++ b/Source/PrivateHeaders/Ably/ARTPushChannel+Private.h @@ -1,6 +1,7 @@ #import #import +@class ARTChannel; @class ARTRestInternal; @class ARTInternalLog; diff --git a/Source/PrivateHeaders/Ably/ARTRealtimeChannel+Private.h b/Source/PrivateHeaders/Ably/ARTRealtimeChannel+Private.h index f8883bf98..fb6bbdf7c 100644 --- a/Source/PrivateHeaders/Ably/ARTRealtimeChannel+Private.h +++ b/Source/PrivateHeaders/Ably/ARTRealtimeChannel+Private.h @@ -3,6 +3,7 @@ // // +#import #import #import #import diff --git a/Source/PrivateHeaders/Ably/ARTRestChannel+Private.h b/Source/PrivateHeaders/Ably/ARTRestChannel+Private.h index 1a484d439..f179996b5 100644 --- a/Source/PrivateHeaders/Ably/ARTRestChannel+Private.h +++ b/Source/PrivateHeaders/Ably/ARTRestChannel+Private.h @@ -3,6 +3,7 @@ // // +#import #import #import #import diff --git a/Source/include/Ably.modulemap b/Source/include/Ably.modulemap index d891ce3b9..b593bbea9 100644 --- a/Source/include/Ably.modulemap +++ b/Source/include/Ably.modulemap @@ -113,5 +113,6 @@ framework module Ably { header "Ably/ARTWrapperSDKProxyRealtime+Private.h" header "Ably/ARTWrapperSDKProxyRealtimeChannels+Private.h" header "Ably/ARTWrapperSDKProxyRealtimeChannel+Private.h" + header "Ably/ARTChannel.h" } } diff --git a/Source/include/Ably/ARTChannel.h b/Source/include/Ably/ARTChannelProtocol.h similarity index 84% rename from Source/include/Ably/ARTChannel.h rename to Source/include/Ably/ARTChannelProtocol.h index 1007e2308..a5ef9912c 100644 --- a/Source/include/Ably/ARTChannel.h +++ b/Source/include/Ably/ARTChannelProtocol.h @@ -13,7 +13,7 @@ NS_ASSUME_NONNULL_BEGIN /** - The protocol upon which the `ARTChannel` is implemented. + The protocol upon which `ARTRestChannelProtocol` and `ARTRealtimeChannelProtocol` are based. */ @protocol ARTChannelProtocol @@ -73,14 +73,4 @@ NS_ASSUME_NONNULL_BEGIN @end -/** - * The base class for `ARTRestChannel` and `ARTRealtimeChannel`. - * Ably platform service organizes the message traffic within applications into named channels. Channels are the medium through which messages are distributed; clients attach to channels to subscribe to messages, and every message published to a unique channel is broadcast by Ably to all subscribers. - * - * @see See `ARTChannelProtocol` for details. - */ -NS_SWIFT_SENDABLE -@interface ARTChannel : NSObject -@end - NS_ASSUME_NONNULL_END diff --git a/Source/include/Ably/ARTPushChannel.h b/Source/include/Ably/ARTPushChannel.h index c6070c46c..aa7b8d380 100644 --- a/Source/include/Ably/ARTPushChannel.h +++ b/Source/include/Ably/ARTPushChannel.h @@ -1,6 +1,5 @@ #import #import -#import @class ARTPushChannelSubscription; @class ARTPaginatedResult; diff --git a/Source/include/Ably/ARTRestChannel.h b/Source/include/Ably/ARTRestChannel.h index 941c52b80..9ea414520 100644 --- a/Source/include/Ably/ARTRestChannel.h +++ b/Source/include/Ably/ARTRestChannel.h @@ -1,6 +1,6 @@ #import -#import +#import @class ARTRest; @class ARTRestPresence; diff --git a/Source/include/Ably/AblyPublic.h b/Source/include/Ably/AblyPublic.h index 42215a989..3a6fbc5f8 100644 --- a/Source/include/Ably/AblyPublic.h +++ b/Source/include/Ably/AblyPublic.h @@ -47,3 +47,4 @@ #import #import #import +#import From f3f328f27392b7d2ff12e530cde22cdc70d5c2f0 Mon Sep 17 00:00:00 2001 From: Lawrence Forooghian Date: Thu, 13 Feb 2025 13:37:20 -0300 Subject: [PATCH 04/16] Remove ARTChannelProtocol conformance from ARTChannel Motivation as in 8796ec8. --- Source/ARTChannel.m | 2 -- Source/PrivateHeaders/Ably/ARTChannel.h | 27 ++++++++++++++++++++++++- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/Source/ARTChannel.m b/Source/ARTChannel.m index 44d14a01e..225b71fc4 100644 --- a/Source/ARTChannel.m +++ b/Source/ARTChannel.m @@ -17,8 +17,6 @@ @implementation ARTChannel { ARTChannelOptions *_options; } -@synthesize name = _name; - - (instancetype)initWithName:(NSString *)name andOptions:(ARTChannelOptions *)options rest:(ARTRestInternal *)rest logger:(ARTInternalLog *)logger { if (self = [super init]) { _name = name; diff --git a/Source/PrivateHeaders/Ably/ARTChannel.h b/Source/PrivateHeaders/Ably/ARTChannel.h index 82e3b267d..44c81414b 100644 --- a/Source/PrivateHeaders/Ably/ARTChannel.h +++ b/Source/PrivateHeaders/Ably/ARTChannel.h @@ -20,7 +20,32 @@ NS_ASSUME_NONNULL_BEGIN * @see See `ARTChannelProtocol` for details. */ NS_SWIFT_SENDABLE -@interface ARTChannel : NSObject +@interface ARTChannel : NSObject + +@property (readonly) NSString *name; + +- (void)publish:(nullable NSString *)name data:(nullable id)data; + +- (void)publish:(nullable NSString *)name data:(nullable id)data callback:(nullable ARTCallback)callback; + +- (void)publish:(nullable NSString *)name data:(nullable id)data clientId:(NSString *)clientId; + +- (void)publish:(nullable NSString *)name data:(nullable id)data clientId:(NSString *)clientId callback:(nullable ARTCallback)callback; + +- (void)publish:(nullable NSString *)name data:(nullable id)data extras:(nullable id)extras; + +- (void)publish:(nullable NSString *)name data:(nullable id)data extras:(nullable id)extras callback:(nullable ARTCallback)callback; + +- (void)publish:(nullable NSString *)name data:(nullable id)data clientId:(NSString *)clientId extras:(nullable id)extras; + +- (void)publish:(nullable NSString *)name data:(nullable id)data clientId:(NSString *)clientId extras:(nullable id)extras callback:(nullable ARTCallback)callback; + +- (void)publish:(NSArray *)messages; + +- (void)publish:(NSArray *)messages callback:(nullable ARTCallback)callback; + +- (void)history:(ARTPaginatedMessagesCallback)callback; + @end NS_ASSUME_NONNULL_END From 00c0f7367ca131bbecf6c33058ce194c414bf064 Mon Sep 17 00:00:00 2001 From: Lawrence Forooghian Date: Wed, 12 Feb 2025 14:35:11 -0300 Subject: [PATCH 05/16] Insert wrapper SDK agents in -history As in b006650. --- Source/ARTChannel.m | 2 +- Source/ARTRealtimeChannel.m | 13 ++-- Source/ARTRestChannel.m | 12 ++-- Source/ARTWrapperSDKProxyRealtimeChannel.m | 7 ++- Source/PrivateHeaders/Ably/ARTChannel.h | 3 +- .../Ably/ARTRealtimeChannel+Private.h | 4 +- .../Ably/ARTRestChannel+Private.h | 2 +- Test/Tests/WrapperSDKProxyTests.swift | 61 +++++++++++++++++-- 8 files changed, 82 insertions(+), 22 deletions(-) diff --git a/Source/ARTChannel.m b/Source/ARTChannel.m index 225b71fc4..e623b3d0f 100644 --- a/Source/ARTChannel.m +++ b/Source/ARTChannel.m @@ -176,7 +176,7 @@ - (ARTMessage *)encodeMessageIfNeeded:(ARTMessage *)message error:(NSError **)er return message; } -- (void)history:(ARTPaginatedMessagesCallback)callback { +- (void)historyWithWrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents completion:(ARTPaginatedMessagesCallback)callback { NSAssert(false, @"-[%@ %@] should always be overriden.", self.class, NSStringFromSelector(_cmd)); } diff --git a/Source/ARTRealtimeChannel.m b/Source/ARTRealtimeChannel.m index 31147a7bd..fd85d21d6 100644 --- a/Source/ARTRealtimeChannel.m +++ b/Source/ARTRealtimeChannel.m @@ -130,7 +130,7 @@ - (void)publish:(NSArray *)messages callback:(nullable ARTCallback } - (void)history:(ARTPaginatedMessagesCallback)callback { - [_internal history:callback]; + [_internal historyWithWrapperSDKAgents:nil completion:callback]; } - (BOOL)exceedMaxSize:(NSArray *)messages { @@ -182,7 +182,7 @@ - (void)unsubscribe:(NSString *)name listener:(ARTEventListener *_Nullable)liste } - (BOOL)history:(ARTRealtimeHistoryQuery *_Nullable)query callback:(ARTPaginatedMessagesCallback)callback error:(NSError *_Nullable *_Nullable)errorPtr { - return [_internal history:query callback:callback error:errorPtr]; + return [_internal history:query wrapperSDKAgents:nil callback:callback error:errorPtr]; } - (ARTEventListener *)on:(ARTChannelStateCallback)cb { @@ -1043,13 +1043,14 @@ - (NSString *)clientId_nosync { return self.realtime.auth.clientId_nosync; } -- (void)history:(ARTPaginatedMessagesCallback)callback { - [self history:[[ARTRealtimeHistoryQuery alloc] init] callback:callback error:nil]; +- (void)historyWithWrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents + completion:(ARTPaginatedMessagesCallback)callback { + [self history:[[ARTRealtimeHistoryQuery alloc] init] wrapperSDKAgents:wrapperSDKAgents callback:callback error:nil]; } -- (BOOL)history:(ARTRealtimeHistoryQuery *)query callback:(ARTPaginatedMessagesCallback)callback error:(NSError **)errorPtr { +- (BOOL)history:(ARTRealtimeHistoryQuery *)query wrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents callback:(ARTPaginatedMessagesCallback)callback error:(NSError **)errorPtr { query.realtimeChannel = self; - return [_restChannel history:query callback:callback error:errorPtr]; + return [_restChannel history:query wrapperSDKAgents:wrapperSDKAgents callback:callback error:errorPtr]; } - (void)startDecodeFailureRecoveryWithErrorInfo:(ARTErrorInfo *)error { diff --git a/Source/ARTRestChannel.m b/Source/ARTRestChannel.m index d1a10fb3b..06def6c75 100644 --- a/Source/ARTRestChannel.m +++ b/Source/ARTRestChannel.m @@ -45,7 +45,7 @@ - (NSString *)name { } - (BOOL)history:(nullable ARTDataQuery *)query callback:(ARTPaginatedMessagesCallback)callback error:(NSError *_Nullable *_Nullable)errorPtr { - return [_internal history:query callback:callback error:errorPtr]; + return [_internal history:query wrapperSDKAgents:nil callback:callback error:errorPtr]; } - (void)status:(ARTChannelDetailsCallback)callback { @@ -93,7 +93,7 @@ - (void)publish:(NSArray *)messages callback:(nullable ARTCallback } - (void)history:(ARTPaginatedMessagesCallback)callback { - [_internal history:callback]; + [_internal historyWithWrapperSDKAgents:nil completion:callback]; } - (ARTChannelOptions *)options { @@ -148,11 +148,11 @@ - (ARTPushChannelInternal *)push { return _pushChannel; } -- (void)history:(ARTPaginatedMessagesCallback)callback { - [self history:[[ARTDataQuery alloc] init] callback:callback error:nil]; +- (void)historyWithWrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents completion:(ARTPaginatedMessagesCallback)callback { + [self history:[[ARTDataQuery alloc] init] wrapperSDKAgents:wrapperSDKAgents callback:callback error:nil]; } -- (BOOL)history:(ARTDataQuery *)query callback:(ARTPaginatedMessagesCallback)callback error:(NSError * __autoreleasing *)errorPtr { +- (BOOL)history:(ARTDataQuery *)query wrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents callback:(ARTPaginatedMessagesCallback)callback error:(NSError * __autoreleasing *)errorPtr { if (callback) { void (^userCallback)(ARTPaginatedResult *result, ARTErrorInfo *error) = callback; callback = ^(ARTPaginatedResult *result, ARTErrorInfo *error) { @@ -210,7 +210,7 @@ - (BOOL)history:(ARTDataQuery *)query callback:(ARTPaginatedMessagesCallback)cal }; ARTLogDebug(self.logger, @"RS:%p C:%p (%@) stats request %@", self->_rest, self, self.name, request); - [ARTPaginatedResult executePaginated:self->_rest withRequest:request andResponseProcessor:responseProcessor wrapperSDKAgents:nil logger:self.logger callback:callback]; + [ARTPaginatedResult executePaginated:self->_rest withRequest:request andResponseProcessor:responseProcessor wrapperSDKAgents:wrapperSDKAgents logger:self.logger callback:callback]; ret = YES; }); return ret; diff --git a/Source/ARTWrapperSDKProxyRealtimeChannel.m b/Source/ARTWrapperSDKProxyRealtimeChannel.m index 76e1fb82a..01a202364 100644 --- a/Source/ARTWrapperSDKProxyRealtimeChannel.m +++ b/Source/ARTWrapperSDKProxyRealtimeChannel.m @@ -1,4 +1,6 @@ #import "ARTWrapperSDKProxyRealtimeChannel+Private.h" +#import "ARTRealtimeChannel+Private.h" +#import "ARTWrapperSDKProxyOptions.h" NS_ASSUME_NONNULL_BEGIN @@ -54,7 +56,8 @@ - (ARTPushChannel *)push { #endif - (void)history:(nonnull ARTPaginatedMessagesCallback)callback { - [self.underlyingChannel history:callback]; + [self.underlyingChannel.internal historyWithWrapperSDKAgents:self.proxyOptions.agents + completion:callback]; } - (void)publish:(nonnull NSArray *)messages { @@ -114,7 +117,7 @@ - (void)detach:(nullable ARTCallback)callback { } - (BOOL)history:(ARTRealtimeHistoryQuery * _Nullable)query callback:(nonnull ARTPaginatedMessagesCallback)callback error:(NSError * _Nullable __autoreleasing * _Nullable)errorPtr { - return [self.underlyingChannel history:query callback:callback error:errorPtr]; + return [self.underlyingChannel.internal history:query wrapperSDKAgents:self.proxyOptions.agents callback:callback error:errorPtr]; } - (void)off { diff --git a/Source/PrivateHeaders/Ably/ARTChannel.h b/Source/PrivateHeaders/Ably/ARTChannel.h index 44c81414b..690e3262a 100644 --- a/Source/PrivateHeaders/Ably/ARTChannel.h +++ b/Source/PrivateHeaders/Ably/ARTChannel.h @@ -44,7 +44,8 @@ NS_SWIFT_SENDABLE - (void)publish:(NSArray *)messages callback:(nullable ARTCallback)callback; -- (void)history:(ARTPaginatedMessagesCallback)callback; +- (void)historyWithWrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents + completion:(ARTPaginatedMessagesCallback)callback; @end diff --git a/Source/PrivateHeaders/Ably/ARTRealtimeChannel+Private.h b/Source/PrivateHeaders/Ably/ARTRealtimeChannel+Private.h index fb6bbdf7c..21785c706 100644 --- a/Source/PrivateHeaders/Ably/ARTRealtimeChannel+Private.h +++ b/Source/PrivateHeaders/Ably/ARTRealtimeChannel+Private.h @@ -86,7 +86,9 @@ NS_ASSUME_NONNULL_BEGIN - (void)unsubscribe:(NSString *)name listener:(ARTEventListener *_Nullable)listener; -- (BOOL)history:(ARTRealtimeHistoryQuery *_Nullable)query callback:(ARTPaginatedMessagesCallback)callback error:(NSError *_Nullable *_Nullable)errorPtr; +- (void)historyWithWrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents + completion:(ARTPaginatedMessagesCallback)callback; +- (BOOL)history:(ARTRealtimeHistoryQuery *_Nullable)query wrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents callback:(ARTPaginatedMessagesCallback)callback error:(NSError *_Nullable *_Nullable)errorPtr; - (void)setOptions:(ARTRealtimeChannelOptions *_Nullable)options callback:(nullable ARTCallback)callback; diff --git a/Source/PrivateHeaders/Ably/ARTRestChannel+Private.h b/Source/PrivateHeaders/Ably/ARTRestChannel+Private.h index f179996b5..eadf65f3c 100644 --- a/Source/PrivateHeaders/Ably/ARTRestChannel+Private.h +++ b/Source/PrivateHeaders/Ably/ARTRestChannel+Private.h @@ -26,7 +26,7 @@ NS_ASSUME_NONNULL_BEGIN @property (readonly, nullable) ARTChannelOptions *options; -- (BOOL)history:(nullable ARTDataQuery *)query callback:(ARTPaginatedMessagesCallback)callback error:(NSError *_Nullable *_Nullable)errorPtr; +- (BOOL)history:(nullable ARTDataQuery *)query wrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents callback:(ARTPaginatedMessagesCallback)callback error:(NSError *_Nullable *_Nullable)errorPtr; - (void)status:(ARTChannelDetailsCallback)callback; diff --git a/Test/Tests/WrapperSDKProxyTests.swift b/Test/Tests/WrapperSDKProxyTests.swift index 0291f70f7..f16818b53 100644 --- a/Test/Tests/WrapperSDKProxyTests.swift +++ b/Test/Tests/WrapperSDKProxyTests.swift @@ -321,6 +321,7 @@ class WrapperSDKProxyTests: XCTestCase { func parameterizedTest_addsWrapperSDKAgentToRequests( test: Test, + expectedRequestCount: Int = 1, performRequest: @escaping (ARTWrapperSDKProxyRealtime) -> Void ) throws { // Given: a wrapper SDK proxy client @@ -338,7 +339,7 @@ class WrapperSDKProxyTests: XCTestCase { performRequest(proxyClient) // Then: The HTTP request all contains the wrapper SDK's agents in the Ably-Agent header - XCTAssertEqual(testHTTPExecutor.requests.count, 1) + XCTAssertEqual(testHTTPExecutor.requests.count, expectedRequestCount) let expectedIdentifier = [ "ably-cocoa/1.2.38", @@ -346,9 +347,9 @@ class WrapperSDKProxyTests: XCTestCase { "my-wrapper-sdk/1.0.0" ].sorted().joined(separator: " ") - let request = try XCTUnwrap(testHTTPExecutor.requests.first) - - XCTAssertEqual(request.allHTTPHeaderFields?["Ably-Agent"], expectedIdentifier) + for request in testHTTPExecutor.requests { + XCTAssertEqual(request.allHTTPHeaderFields?["Ably-Agent"], expectedIdentifier) + } } func test_time_addsWrapperSDKAgentToRequest() throws { @@ -364,6 +365,58 @@ class WrapperSDKProxyTests: XCTestCase { } } + func test_history_addsWrapperSDKAgentToRequest() throws { + let test = Test() + + try parameterizedTest_addsWrapperSDKAgentToRequests(test: test, expectedRequestCount: 3) { proxyClient in + // Publish some messages so that we can use the history API to fetch them + let channel = proxyClient.channels.get(test.uniqueChannelName()) + for i in 1...2 { + waitUntil(timeout: testTimeout) { done in + channel.publish(nil, data: "\(i)") { error in + XCTAssertNil(error) + done() + } + } + } + + waitUntil(timeout: testTimeout) { done in + let query = ARTRealtimeHistoryQuery() + query.limit = 1 + + do { + try channel.history(query) { firstPage, error in + XCTAssertNil(error) + + guard let firstPage else { + done() + return + } + + // This test also doubles up as a smoke test that `-first` and `-next` on a normal ARTPaginatedResult (as opposed to an ARTHTTPPaginatedResponse) add the SDK agent + + firstPage.first { firstPageAgain, error in + XCTAssertNil(error) + + guard let firstPageAgain else { + done() + return + } + + firstPageAgain.next { _, error in + XCTAssertNil(error) + done() + } + } + } + } catch { + XCTFail("history threw error \(error)") + done() + } + } + } + } + // MARK: - `agent` channel param private func parameterizedTest_checkAttachProtocolMessage( From 24a9f8e085637cd8bd5937e9cb329d6f17e7c309 Mon Sep 17 00:00:00 2001 From: Lawrence Forooghian Date: Wed, 12 Feb 2025 13:15:51 -0300 Subject: [PATCH 06/16] Insert wrapper SDK agents in -stats As in b006650. --- Source/ARTRealtime.m | 14 ++++++++------ Source/ARTRest.m | 14 ++++++++------ Source/ARTWrapperSDKProxyRealtime.m | 10 ++++++---- Source/PrivateHeaders/Ably/ARTRealtime+Private.h | 5 +++-- Source/PrivateHeaders/Ably/ARTRest+Private.h | 4 +++- Test/Tests/RealtimeClientTests.swift | 2 +- Test/Tests/WrapperSDKProxyTests.swift | 13 +++++++++++++ 7 files changed, 42 insertions(+), 20 deletions(-) diff --git a/Source/ARTRealtime.m b/Source/ARTRealtime.m index 5abddaff1..dfe879096 100644 --- a/Source/ARTRealtime.m +++ b/Source/ARTRealtime.m @@ -169,11 +169,12 @@ - (void)ping:(ARTCallback)cb { } - (BOOL)stats:(ARTPaginatedStatsCallback)callback { - return [_internal stats:callback]; + return [_internal statsWithWrapperSDKAgents:nil + callback:callback]; } - (BOOL)stats:(nullable ARTStatsQuery *)query callback:(ARTPaginatedStatsCallback)callback error:(NSError **)errorPtr { - return [_internal stats:query callback:callback error:errorPtr]; + return [_internal stats:query wrapperSDKAgents:nil callback:callback error:errorPtr]; } - (void)connect { @@ -556,12 +557,13 @@ - (void)ping:(ARTCallback) cb { }); } -- (BOOL)stats:(ARTPaginatedStatsCallback)callback { - return [self stats:[[ARTStatsQuery alloc] init] callback:callback error:nil]; +- (BOOL)statsWithWrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents + callback:(ARTPaginatedStatsCallback)callback { + return [self stats:[[ARTStatsQuery alloc] init] wrapperSDKAgents:wrapperSDKAgents callback:callback error:nil]; } -- (BOOL)stats:(ARTStatsQuery *)query callback:(ARTPaginatedStatsCallback)callback error:(NSError **)errorPtr { - return [self.rest stats:query callback:callback error:errorPtr]; +- (BOOL)stats:(ARTStatsQuery *)query wrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents callback:(ARTPaginatedStatsCallback)callback error:(NSError **)errorPtr { + return [self.rest stats:query wrapperSDKAgents:wrapperSDKAgents callback:callback error:errorPtr]; } - (void)performTransitionToDisconnectedOrSuspendedWithParams:(ARTConnectionStateChangeParams *)params { diff --git a/Source/ARTRest.m b/Source/ARTRest.m index 2b84f1149..8796f64c8 100644 --- a/Source/ARTRest.m +++ b/Source/ARTRest.m @@ -117,11 +117,12 @@ - (BOOL)request:(NSString *)method } - (BOOL)stats:(ARTPaginatedStatsCallback)callback { - return [_internal stats:callback]; + return [_internal statsWithWrapperSDKAgents:nil + completion:callback]; } - (BOOL)stats:(nullable ARTStatsQuery *)query callback:(ARTPaginatedStatsCallback)callback error:(NSError *_Nullable *_Nullable)errorPtr { - return [_internal stats:query callback:callback error:errorPtr]; + return [_internal stats:query wrapperSDKAgents:nil callback:callback error:errorPtr]; } - (ARTRestChannels *)channels { @@ -680,11 +681,12 @@ - (BOOL)request:(NSString *)method }]; } -- (BOOL)stats:(ARTPaginatedStatsCallback)callback { - return [self stats:[[ARTStatsQuery alloc] init] callback:callback error:nil]; +- (BOOL)statsWithWrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents + completion:(ARTPaginatedStatsCallback)callback { + return [self stats:[[ARTStatsQuery alloc] init] wrapperSDKAgents:wrapperSDKAgents callback:callback error:nil]; } -- (BOOL)stats:(ARTStatsQuery *)query callback:(ARTPaginatedStatsCallback)callback error:(NSError **)errorPtr { +- (BOOL)stats:(ARTStatsQuery *)query wrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents callback:(ARTPaginatedStatsCallback)callback error:(NSError **)errorPtr { if (callback) { ARTPaginatedStatsCallback userCallback = callback; callback = ^(ARTPaginatedResult *r, ARTErrorInfo *e) { @@ -727,7 +729,7 @@ - (BOOL)stats:(ARTStatsQuery *)query callback:(ARTPaginatedStatsCallback)callbac }; dispatch_async(_queue, ^{ - [ARTPaginatedResult executePaginated:self withRequest:request andResponseProcessor:responseProcessor wrapperSDKAgents:nil logger:self.logger callback:callback]; + [ARTPaginatedResult executePaginated:self withRequest:request andResponseProcessor:responseProcessor wrapperSDKAgents:wrapperSDKAgents logger:self.logger callback:callback]; }); return YES; } diff --git a/Source/ARTWrapperSDKProxyRealtime.m b/Source/ARTWrapperSDKProxyRealtime.m index d465b8b49..9aa37010d 100644 --- a/Source/ARTWrapperSDKProxyRealtime.m +++ b/Source/ARTWrapperSDKProxyRealtime.m @@ -80,13 +80,15 @@ - (BOOL)request:(nonnull NSString *)method } - (BOOL)stats:(nonnull ARTPaginatedStatsCallback)callback { - return [self.underlyingRealtime stats:callback]; + return [self.underlyingRealtime.internal statsWithWrapperSDKAgents:self.proxyOptions.agents + callback:callback]; } - (BOOL)stats:(nullable ARTStatsQuery *)query callback:(nonnull ARTPaginatedStatsCallback)callback error:(NSError * _Nullable __autoreleasing * _Nullable)errorPtr { - return [self.underlyingRealtime stats:query - callback:callback - error:errorPtr]; + return [self.underlyingRealtime.internal stats:query + wrapperSDKAgents:self.proxyOptions.agents + callback:callback + error:errorPtr]; } - (void)time:(nonnull ARTDateTimeCallback)callback { diff --git a/Source/PrivateHeaders/Ably/ARTRealtime+Private.h b/Source/PrivateHeaders/Ably/ARTRealtime+Private.h index 3aaea8bcf..670f20427 100644 --- a/Source/PrivateHeaders/Ably/ARTRealtime+Private.h +++ b/Source/PrivateHeaders/Ably/ARTRealtime+Private.h @@ -59,9 +59,10 @@ wrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents - (void)ping:(ARTCallback)cb; -- (BOOL)stats:(ARTPaginatedStatsCallback)callback; +- (BOOL)statsWithWrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents + callback:(ARTPaginatedStatsCallback)callback; -- (BOOL)stats:(nullable ARTStatsQuery *)query callback:(ARTPaginatedStatsCallback)callback error:(NSError *_Nullable *_Nullable)errorPtr; +- (BOOL)stats:(nullable ARTStatsQuery *)query wrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents callback:(ARTPaginatedStatsCallback)callback error:(NSError *_Nullable *_Nullable)errorPtr; - (void)connect; diff --git a/Source/PrivateHeaders/Ably/ARTRest+Private.h b/Source/PrivateHeaders/Ably/ARTRest+Private.h index a149382f4..fbfd3171f 100644 --- a/Source/PrivateHeaders/Ably/ARTRest+Private.h +++ b/Source/PrivateHeaders/Ably/ARTRest+Private.h @@ -106,9 +106,11 @@ wrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents callback:(ARTHTTPPaginatedCallback)callback error:(NSError *_Nullable *_Nullable)errorPtr; -- (BOOL)stats:(ARTPaginatedStatsCallback)callback; +- (BOOL)statsWithWrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents + completion:(ARTPaginatedStatsCallback)callback; - (BOOL)stats:(nullable ARTStatsQuery *)query +wrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents callback:(ARTPaginatedStatsCallback)callback error:(NSError *_Nullable *_Nullable)errorPtr; diff --git a/Test/Tests/RealtimeClientTests.swift b/Test/Tests/RealtimeClientTests.swift index d77041f9c..2bc067bbe 100644 --- a/Test/Tests/RealtimeClientTests.swift +++ b/Test/Tests/RealtimeClientTests.swift @@ -348,7 +348,7 @@ class RealtimeClientTests: XCTestCase { // Rest waitUntil(timeout: testTimeout) { done in expect { - try client.internal.rest.stats(query, callback: { paginated, error in + try client.internal.rest.stats(query, wrapperSDKAgents:nil, callback: { paginated, error in defer { done() } if let e = error { XCTFail(e.localizedDescription) diff --git a/Test/Tests/WrapperSDKProxyTests.swift b/Test/Tests/WrapperSDKProxyTests.swift index f16818b53..36657425b 100644 --- a/Test/Tests/WrapperSDKProxyTests.swift +++ b/Test/Tests/WrapperSDKProxyTests.swift @@ -417,6 +417,19 @@ class WrapperSDKProxyTests: XCTestCase { } } + func test_stats_addsWrapperSDKAgentToRequest() throws { + let test = Test() + + try parameterizedTest_addsWrapperSDKAgentToRequests(test: test) { proxyClient in + waitUntil(timeout: testTimeout) { done in + proxyClient.stats() { _, error in + XCTAssertNil(error) + done() + } + } + } + } + // MARK: - `agent` channel param private func parameterizedTest_checkAttachProtocolMessage( From ebd733748ff65328ed89e2fe29b36fc4d73e13a9 Mon Sep 17 00:00:00 2001 From: Lawrence Forooghian Date: Wed, 12 Feb 2025 15:09:53 -0300 Subject: [PATCH 07/16] Create wrapper SDK proxy push As in 4daf4ba. --- Ably.xcodeproj/project.pbxproj | 24 ++++++ Source/ARTWrapperSDKProxyPush.m | 73 +++++++++++++++++++ Source/ARTWrapperSDKProxyRealtime.m | 7 +- Source/Ably.modulemap | 1 + .../Ably/ARTWrapperSDKProxyPush+Private.h | 14 ++++ Source/include/Ably.modulemap | 1 + Source/include/Ably/ARTWrapperSDKProxyPush.h | 22 ++++++ .../include/Ably/ARTWrapperSDKProxyRealtime.h | 4 +- Source/include/Ably/AblyInternal.h | 1 + 9 files changed, 141 insertions(+), 6 deletions(-) create mode 100644 Source/ARTWrapperSDKProxyPush.m create mode 100644 Source/PrivateHeaders/Ably/ARTWrapperSDKProxyPush+Private.h create mode 100644 Source/include/Ably/ARTWrapperSDKProxyPush.h diff --git a/Ably.xcodeproj/project.pbxproj b/Ably.xcodeproj/project.pbxproj index 099e0c2aa..faae2f712 100644 --- a/Ably.xcodeproj/project.pbxproj +++ b/Ably.xcodeproj/project.pbxproj @@ -208,6 +208,15 @@ 2147F03529E5872C0071CB94 /* MockInternalLogCore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2147F03429E5872C0071CB94 /* MockInternalLogCore.swift */; }; 2147F03629E5872C0071CB94 /* MockInternalLogCore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2147F03429E5872C0071CB94 /* MockInternalLogCore.swift */; }; 2147F03729E5872C0071CB94 /* MockInternalLogCore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2147F03429E5872C0071CB94 /* MockInternalLogCore.swift */; }; + 2159248B2D636826004A235C /* ARTWrapperSDKProxyPush.h in Headers */ = {isa = PBXBuildFile; fileRef = 2159248A2D636826004A235C /* ARTWrapperSDKProxyPush.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2159248C2D636826004A235C /* ARTWrapperSDKProxyPush.h in Headers */ = {isa = PBXBuildFile; fileRef = 2159248A2D636826004A235C /* ARTWrapperSDKProxyPush.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2159248D2D636826004A235C /* ARTWrapperSDKProxyPush.h in Headers */ = {isa = PBXBuildFile; fileRef = 2159248A2D636826004A235C /* ARTWrapperSDKProxyPush.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2159248F2D636839004A235C /* ARTWrapperSDKProxyPush+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 2159248E2D636839004A235C /* ARTWrapperSDKProxyPush+Private.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 215924902D636839004A235C /* ARTWrapperSDKProxyPush+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 2159248E2D636839004A235C /* ARTWrapperSDKProxyPush+Private.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 215924912D636839004A235C /* ARTWrapperSDKProxyPush+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 2159248E2D636839004A235C /* ARTWrapperSDKProxyPush+Private.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 215924932D636A6E004A235C /* ARTWrapperSDKProxyPush.m in Sources */ = {isa = PBXBuildFile; fileRef = 215924922D636A6E004A235C /* ARTWrapperSDKProxyPush.m */; }; + 215924942D636A6E004A235C /* ARTWrapperSDKProxyPush.m in Sources */ = {isa = PBXBuildFile; fileRef = 215924922D636A6E004A235C /* ARTWrapperSDKProxyPush.m */; }; + 215924952D636A6E004A235C /* ARTWrapperSDKProxyPush.m in Sources */ = {isa = PBXBuildFile; fileRef = 215924922D636A6E004A235C /* ARTWrapperSDKProxyPush.m */; }; 215F75F82922B1DB009E0E76 /* ARTClientInformation.h in Headers */ = {isa = PBXBuildFile; fileRef = 215F75F62922B1DB009E0E76 /* ARTClientInformation.h */; settings = {ATTRIBUTES = (Public, ); }; }; 215F75F92922B1DB009E0E76 /* ARTClientInformation.h in Headers */ = {isa = PBXBuildFile; fileRef = 215F75F62922B1DB009E0E76 /* ARTClientInformation.h */; settings = {ATTRIBUTES = (Public, ); }; }; 215F75FA2922B1DB009E0E76 /* ARTClientInformation.h in Headers */ = {isa = PBXBuildFile; fileRef = 215F75F62922B1DB009E0E76 /* ARTClientInformation.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -1241,6 +1250,9 @@ 2147F02C29E583AD0071CB94 /* ARTInternalLogCore.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ARTInternalLogCore.h; path = PrivateHeaders/Ably/ARTInternalLogCore.h; sourceTree = ""; }; 2147F03029E583CE0071CB94 /* ARTInternalLogCore.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ARTInternalLogCore.m; sourceTree = ""; }; 2147F03429E5872C0071CB94 /* MockInternalLogCore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockInternalLogCore.swift; sourceTree = ""; }; + 2159248A2D636826004A235C /* ARTWrapperSDKProxyPush.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ARTWrapperSDKProxyPush.h; path = include/Ably/ARTWrapperSDKProxyPush.h; sourceTree = ""; }; + 2159248E2D636839004A235C /* ARTWrapperSDKProxyPush+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "ARTWrapperSDKProxyPush+Private.h"; path = "PrivateHeaders/Ably/ARTWrapperSDKProxyPush+Private.h"; sourceTree = ""; }; + 215924922D636A6E004A235C /* ARTWrapperSDKProxyPush.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ARTWrapperSDKProxyPush.m; sourceTree = ""; }; 215F75F62922B1DB009E0E76 /* ARTClientInformation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ARTClientInformation.h; path = include/Ably/ARTClientInformation.h; sourceTree = ""; }; 215F75F72922B1DB009E0E76 /* ARTClientInformation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ARTClientInformation.m; sourceTree = ""; }; 215F75FE2922B30F009E0E76 /* ClientInformationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClientInformationTests.swift; sourceTree = ""; }; @@ -1667,6 +1679,9 @@ 21AC0CC02D4AA0630030BD23 /* ARTWrapperSDKProxyRealtimeChannel.h */, 21AC0CC82D4AA0F50030BD23 /* ARTWrapperSDKProxyRealtimeChannel+Private.h */, 21AC0CD02D4AA3200030BD23 /* ARTWrapperSDKProxyRealtimeChannel.m */, + 2159248A2D636826004A235C /* ARTWrapperSDKProxyPush.h */, + 2159248E2D636839004A235C /* ARTWrapperSDKProxyPush+Private.h */, + 215924922D636A6E004A235C /* ARTWrapperSDKProxyPush.m */, ); name = "Wrapper SDK Proxy"; sourceTree = ""; @@ -2416,6 +2431,7 @@ D7D06F0826330E2800DEBDAD /* ARTHttp+Private.h in Headers */, EB1B541922FB1D7F006A59AC /* ARTPushChannelSubscriptions+Private.h in Headers */, 2105ED1E29E7242400DE6D67 /* ARTLogAdapter+Testing.h in Headers */, + 2159248D2D636826004A235C /* ARTWrapperSDKProxyPush.h in Headers */, 21E5D8812D5E3EC300526C4C /* ARTChannelProtocol.h in Headers */, EBF2285B1F4D9AD6009091DD /* ARTWebSocketTransport+Private.h in Headers */, EBFFAC191E97919C003E7326 /* ARTLocalDevice+Private.h in Headers */, @@ -2482,6 +2498,7 @@ EB1B541522FB1CE1006A59AC /* ARTPushDeviceRegistrations+Private.h in Headers */, D7D8F82B1BC2C706009718F2 /* ARTTokenRequest.h in Headers */, 2147F02D29E583AD0071CB94 /* ARTInternalLogCore.h in Headers */, + 2159248F2D636839004A235C /* ARTWrapperSDKProxyPush+Private.h in Headers */, D5BB211126AA993E00AA5F3E /* ARTNSURL+ARTUtils.h in Headers */, 84039A4C2C811F49001C053E /* ARTChannelOptions+Private.h in Headers */, EB1AE0CC1C5C1EB200D62250 /* ARTEventEmitter+Private.h in Headers */, @@ -2537,6 +2554,7 @@ D710D64521949E61008F54AD /* ARTEventEmitter+Private.h in Headers */, 2105ED2329E7429E00DE6D67 /* ARTPaginatedResult+Subclass.h in Headers */, D710D4D121949BC0008F54AD /* ARTPresence+Private.h in Headers */, + 2159248C2D636826004A235C /* ARTWrapperSDKProxyPush.h in Headers */, 21088DC42A5354F10033C722 /* ARTConnectRetryState.h in Headers */, 2105ED2729E830D600DE6D67 /* ARTInternalLog+Testing.h in Headers */, D710D69021949EFF008F54AD /* ARTCrypto.h in Headers */, @@ -2627,6 +2645,7 @@ D710D56A21949CB9008F54AD /* ARTPushAdmin.h in Headers */, D710D48321949A4E008F54AD /* ARTDefault+Private.h in Headers */, D70C36C4233E6831002FD6E3 /* ARTFormEncode.h in Headers */, + 215924902D636839004A235C /* ARTWrapperSDKProxyPush+Private.h in Headers */, D710D59021949D29008F54AD /* ARTStatus.h in Headers */, D5BB213A26AAA60500AA5F3E /* ARTNSError+ARTUtils.h in Headers */, D710D61D21949DEC008F54AD /* ARTHTTPPaginatedResponse+Private.h in Headers */, @@ -2718,6 +2737,7 @@ D710D5AD21949D2A008F54AD /* ARTChannelOptions.h in Headers */, 2105ED2429E7429E00DE6D67 /* ARTPaginatedResult+Subclass.h in Headers */, D710D64B21949E62008F54AD /* ARTEventEmitter+Private.h in Headers */, + 2159248B2D636826004A235C /* ARTWrapperSDKProxyPush.h in Headers */, 21088DC52A5354F10033C722 /* ARTConnectRetryState.h in Headers */, 2105ED2829E830D600DE6D67 /* ARTInternalLog+Testing.h in Headers */, D710D4D321949BC1008F54AD /* ARTPresence+Private.h in Headers */, @@ -2808,6 +2828,7 @@ EB1B53FF22F8D91C006A59AC /* ARTQueuedDealloc.h in Headers */, D710D57021949CBA008F54AD /* ARTPushAdmin.h in Headers */, D710D48521949A4F008F54AD /* ARTDefault+Private.h in Headers */, + 215924912D636839004A235C /* ARTWrapperSDKProxyPush+Private.h in Headers */, D70C36C5233E6831002FD6E3 /* ARTFormEncode.h in Headers */, D710D5B621949D2A008F54AD /* ARTStatus.h in Headers */, D710D62921949DED008F54AD /* ARTHTTPPaginatedResponse+Private.h in Headers */, @@ -3237,6 +3258,7 @@ EB89D40B1C61C6EA007FA5B7 /* ARTRealtimeChannels.m in Sources */, 217D183B254222F600DFF07E /* ARTSRDelegateController.m in Sources */, D746AE231BBB60EE003ECEF8 /* ARTChannel.m in Sources */, + 215924932D636A6E004A235C /* ARTWrapperSDKProxyPush.m in Sources */, D76F153C23DB010C00B5133C /* ARTRealtimeChannelOptions.m in Sources */, D769E15421270F3400DC5CD1 /* ARTHTTPPaginatedResponse.m in Sources */, D7DEAFD21E65926D00D23F24 /* ARTLocalDevice.m in Sources */, @@ -3485,6 +3507,7 @@ D710D53121949C54008F54AD /* ARTPush.m in Sources */, 217D1852254222F700DFF07E /* ARTSRDelegateController.m in Sources */, D710D5E021949D78008F54AD /* ARTStats.m in Sources */, + 215924942D636A6E004A235C /* ARTWrapperSDKProxyPush.m in Sources */, D76F153F23DB013000B5133C /* ARTRealtimeChannelOptions.m in Sources */, D710D4F121949C0D008F54AD /* ARTQueuedMessage.m in Sources */, D710D49521949AC2008F54AD /* ARTRest.m in Sources */, @@ -3613,6 +3636,7 @@ 217D1869254222FA00DFF07E /* ARTSRDelegateController.m in Sources */, D710D60621949D79008F54AD /* ARTStats.m in Sources */, D76F154023DB013000B5133C /* ARTRealtimeChannelOptions.m in Sources */, + 215924952D636A6E004A235C /* ARTWrapperSDKProxyPush.m in Sources */, D710D50121949C0E008F54AD /* ARTQueuedMessage.m in Sources */, D710D49721949AC3008F54AD /* ARTRest.m in Sources */, D710D54B21949C55008F54AD /* ARTNSMutableRequest+ARTPush.m in Sources */, diff --git a/Source/ARTWrapperSDKProxyPush.m b/Source/ARTWrapperSDKProxyPush.m new file mode 100644 index 000000000..9e64dd00b --- /dev/null +++ b/Source/ARTWrapperSDKProxyPush.m @@ -0,0 +1,73 @@ +#import "ARTWrapperSDKProxyPush+Private.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface ARTWrapperSDKProxyPush () + +@property (nonatomic, readonly) ARTPush *underlyingPush; +@property (nonatomic, readonly) ARTWrapperSDKProxyOptions *proxyOptions; + +@end + +NS_ASSUME_NONNULL_END + +@implementation ARTWrapperSDKProxyPush + +- (instancetype)initWithPush:(ARTPush *)push proxyOptions:(ARTWrapperSDKProxyOptions *)proxyOptions { + if (self = [super init]) { + _underlyingPush = push; + _proxyOptions = proxyOptions; + } + + return self; +} + +- (ARTPushAdmin *)admin { + return self.underlyingPush.admin; +} + +#if TARGET_OS_IOS + +- (void)activate { + [self.underlyingPush activate]; +} + +- (void)deactivate { + [self.underlyingPush deactivate]; +} + ++ (void)didFailToRegisterForLocationNotificationsWithError:(nonnull NSError *)error realtime:(nonnull ARTRealtime *)realtime { + [ARTPush didFailToRegisterForLocationNotificationsWithError:error realtime:realtime]; +} + ++ (void)didFailToRegisterForLocationNotificationsWithError:(nonnull NSError *)error rest:(nonnull ARTRest *)rest { + [ARTPush didFailToRegisterForLocationNotificationsWithError:error rest:rest]; +} + ++ (void)didFailToRegisterForRemoteNotificationsWithError:(nonnull NSError *)error realtime:(nonnull ARTRealtime *)realtime { + [ARTPush didFailToRegisterForRemoteNotificationsWithError:error realtime:realtime]; +} + ++ (void)didFailToRegisterForRemoteNotificationsWithError:(nonnull NSError *)error rest:(nonnull ARTRest *)rest { + [ARTPush didFailToRegisterForRemoteNotificationsWithError:error rest:rest]; +} + ++ (void)didRegisterForLocationNotificationsWithDeviceToken:(nonnull NSData *)deviceToken realtime:(nonnull ARTRealtime *)realtime { + [ARTPush didRegisterForLocationNotificationsWithDeviceToken:deviceToken realtime:realtime]; +} + ++ (void)didRegisterForLocationNotificationsWithDeviceToken:(nonnull NSData *)deviceToken rest:(nonnull ARTRest *)rest { + [ARTPush didRegisterForLocationNotificationsWithDeviceToken:deviceToken rest:rest]; +} + ++ (void)didRegisterForRemoteNotificationsWithDeviceToken:(nonnull NSData *)deviceToken realtime:(nonnull ARTRealtime *)realtime { + [ARTPush didRegisterForRemoteNotificationsWithDeviceToken:deviceToken realtime:realtime]; +} + ++ (void)didRegisterForRemoteNotificationsWithDeviceToken:(nonnull NSData *)deviceToken rest:(nonnull ARTRest *)rest { + [ARTPush didRegisterForRemoteNotificationsWithDeviceToken:deviceToken rest:rest]; +} + +#endif + +@end diff --git a/Source/ARTWrapperSDKProxyRealtime.m b/Source/ARTWrapperSDKProxyRealtime.m index 9aa37010d..858a0682a 100644 --- a/Source/ARTWrapperSDKProxyRealtime.m +++ b/Source/ARTWrapperSDKProxyRealtime.m @@ -1,5 +1,6 @@ #import "ARTWrapperSDKProxyRealtime+Private.h" #import "ARTWrapperSDKProxyRealtimeChannels+Private.h" +#import "ARTWrapperSDKProxyPush+Private.h" #import "ARTWrapperSDKProxyOptions.h" #import "ARTRealtime+Private.h" @@ -23,6 +24,8 @@ - (instancetype)initWithRealtime:(ARTRealtime *)realtime _proxyOptions = proxyOptions; _channels = [[ARTWrapperSDKProxyRealtimeChannels alloc] initWithChannels:realtime.channels proxyOptions:proxyOptions]; + _push = [[ARTWrapperSDKProxyPush alloc] initWithPush:realtime.push + proxyOptions:proxyOptions]; } return self; @@ -32,10 +35,6 @@ - (ARTConnection *)connection { return self.underlyingRealtime.connection; } -- (ARTPush *)push { - return self.underlyingRealtime.push; -} - - (ARTAuth *)auth { return self.underlyingRealtime.auth; } diff --git a/Source/Ably.modulemap b/Source/Ably.modulemap index b59c570c7..8a46bb864 100644 --- a/Source/Ably.modulemap +++ b/Source/Ably.modulemap @@ -116,5 +116,6 @@ framework module Ably { header "ARTWrapperSDKProxyRealtimeChannels+Private.h" header "ARTWrapperSDKProxyRealtimeChannel+Private.h" header "ARTChannel.h" + header "ARTWrapperSDKProxyPush+Private.h" } } diff --git a/Source/PrivateHeaders/Ably/ARTWrapperSDKProxyPush+Private.h b/Source/PrivateHeaders/Ably/ARTWrapperSDKProxyPush+Private.h new file mode 100644 index 000000000..7624bf874 --- /dev/null +++ b/Source/PrivateHeaders/Ably/ARTWrapperSDKProxyPush+Private.h @@ -0,0 +1,14 @@ +#import + +@class ARTWrapperSDKProxyOptions; + +NS_ASSUME_NONNULL_BEGIN + +@interface ARTWrapperSDKProxyPush () + +- (instancetype)initWithPush:(ARTPush *)push + proxyOptions:(ARTWrapperSDKProxyOptions *)proxyOptions NS_DESIGNATED_INITIALIZER; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Source/include/Ably.modulemap b/Source/include/Ably.modulemap index b593bbea9..5b93f3d76 100644 --- a/Source/include/Ably.modulemap +++ b/Source/include/Ably.modulemap @@ -114,5 +114,6 @@ framework module Ably { header "Ably/ARTWrapperSDKProxyRealtimeChannels+Private.h" header "Ably/ARTWrapperSDKProxyRealtimeChannel+Private.h" header "Ably/ARTChannel.h" + header "Ably/ARTWrapperSDKProxyPush+Private.h" } } diff --git a/Source/include/Ably/ARTWrapperSDKProxyPush.h b/Source/include/Ably/ARTWrapperSDKProxyPush.h new file mode 100644 index 000000000..deb7abc8a --- /dev/null +++ b/Source/include/Ably/ARTWrapperSDKProxyPush.h @@ -0,0 +1,22 @@ +#import +#import + +@class ARTPushAdmin; + +NS_ASSUME_NONNULL_BEGIN + +/** + * An object which wraps an instance of `ARTPush` and provides a similar API. It allows Ably-authored wrapper SDKs to send analytics information so that Ably can track the usage of the wrapper SDK. + * + * - Important: This class should only be used by Ably-authored SDKs. + */ +NS_SWIFT_SENDABLE +@interface ARTWrapperSDKProxyPush : NSObject + +- (instancetype)init NS_UNAVAILABLE; + +@property (readonly) ARTPushAdmin *admin; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Source/include/Ably/ARTWrapperSDKProxyRealtime.h b/Source/include/Ably/ARTWrapperSDKProxyRealtime.h index 2250df095..1003ecaae 100644 --- a/Source/include/Ably/ARTWrapperSDKProxyRealtime.h +++ b/Source/include/Ably/ARTWrapperSDKProxyRealtime.h @@ -3,7 +3,7 @@ @class ARTConnection; @class ARTWrapperSDKProxyRealtimeChannels; -@class ARTPush; +@class ARTWrapperSDKProxyPush; @class ARTAuth; NS_ASSUME_NONNULL_BEGIN @@ -20,7 +20,7 @@ NS_SWIFT_SENDABLE @property (readonly) ARTConnection *connection; @property (readonly) ARTWrapperSDKProxyRealtimeChannels *channels; -@property (readonly) ARTPush *push; +@property (readonly) ARTWrapperSDKProxyPush *push; @property (readonly) ARTAuth *auth; @end diff --git a/Source/include/Ably/AblyInternal.h b/Source/include/Ably/AblyInternal.h index 8028836ed..6aa845c15 100644 --- a/Source/include/Ably/AblyInternal.h +++ b/Source/include/Ably/AblyInternal.h @@ -5,3 +5,4 @@ #import #import #import +#import From 6f0fa3469f086a05208ceec960c0e8d6bf92554d Mon Sep 17 00:00:00 2001 From: Lawrence Forooghian Date: Wed, 12 Feb 2025 16:15:33 -0300 Subject: [PATCH 08/16] Create wrapper SDK proxy push admin As in 4daf4ba. --- Ably.xcodeproj/project.pbxproj | 24 ++++++++++++ Source/ARTWrapperSDKProxyPush.m | 7 ++-- Source/ARTWrapperSDKProxyPushAdmin.m | 39 +++++++++++++++++++ Source/Ably.modulemap | 1 + .../ARTWrapperSDKProxyPushAdmin+Private.h | 14 +++++++ Source/include/Ably.modulemap | 1 + Source/include/Ably/ARTWrapperSDKProxyPush.h | 4 +- .../Ably/ARTWrapperSDKProxyPushAdmin.h | 24 ++++++++++++ Source/include/Ably/AblyInternal.h | 1 + 9 files changed, 109 insertions(+), 6 deletions(-) create mode 100644 Source/ARTWrapperSDKProxyPushAdmin.m create mode 100644 Source/PrivateHeaders/Ably/ARTWrapperSDKProxyPushAdmin+Private.h create mode 100644 Source/include/Ably/ARTWrapperSDKProxyPushAdmin.h diff --git a/Ably.xcodeproj/project.pbxproj b/Ably.xcodeproj/project.pbxproj index faae2f712..074d6632b 100644 --- a/Ably.xcodeproj/project.pbxproj +++ b/Ably.xcodeproj/project.pbxproj @@ -217,6 +217,15 @@ 215924932D636A6E004A235C /* ARTWrapperSDKProxyPush.m in Sources */ = {isa = PBXBuildFile; fileRef = 215924922D636A6E004A235C /* ARTWrapperSDKProxyPush.m */; }; 215924942D636A6E004A235C /* ARTWrapperSDKProxyPush.m in Sources */ = {isa = PBXBuildFile; fileRef = 215924922D636A6E004A235C /* ARTWrapperSDKProxyPush.m */; }; 215924952D636A6E004A235C /* ARTWrapperSDKProxyPush.m in Sources */ = {isa = PBXBuildFile; fileRef = 215924922D636A6E004A235C /* ARTWrapperSDKProxyPush.m */; }; + 215924972D636AC5004A235C /* ARTWrapperSDKProxyPushAdmin.h in Headers */ = {isa = PBXBuildFile; fileRef = 215924962D636AC5004A235C /* ARTWrapperSDKProxyPushAdmin.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 215924982D636AC5004A235C /* ARTWrapperSDKProxyPushAdmin.h in Headers */ = {isa = PBXBuildFile; fileRef = 215924962D636AC5004A235C /* ARTWrapperSDKProxyPushAdmin.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 215924992D636AC5004A235C /* ARTWrapperSDKProxyPushAdmin.h in Headers */ = {isa = PBXBuildFile; fileRef = 215924962D636AC5004A235C /* ARTWrapperSDKProxyPushAdmin.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2159249B2D636AD5004A235C /* ARTWrapperSDKProxyPushAdmin+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 2159249A2D636AD5004A235C /* ARTWrapperSDKProxyPushAdmin+Private.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 2159249C2D636AD5004A235C /* ARTWrapperSDKProxyPushAdmin+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 2159249A2D636AD5004A235C /* ARTWrapperSDKProxyPushAdmin+Private.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 2159249D2D636AD5004A235C /* ARTWrapperSDKProxyPushAdmin+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 2159249A2D636AD5004A235C /* ARTWrapperSDKProxyPushAdmin+Private.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 2159249F2D636ADF004A235C /* ARTWrapperSDKProxyPushAdmin.m in Sources */ = {isa = PBXBuildFile; fileRef = 2159249E2D636ADF004A235C /* ARTWrapperSDKProxyPushAdmin.m */; }; + 215924A02D636ADF004A235C /* ARTWrapperSDKProxyPushAdmin.m in Sources */ = {isa = PBXBuildFile; fileRef = 2159249E2D636ADF004A235C /* ARTWrapperSDKProxyPushAdmin.m */; }; + 215924A12D636ADF004A235C /* ARTWrapperSDKProxyPushAdmin.m in Sources */ = {isa = PBXBuildFile; fileRef = 2159249E2D636ADF004A235C /* ARTWrapperSDKProxyPushAdmin.m */; }; 215F75F82922B1DB009E0E76 /* ARTClientInformation.h in Headers */ = {isa = PBXBuildFile; fileRef = 215F75F62922B1DB009E0E76 /* ARTClientInformation.h */; settings = {ATTRIBUTES = (Public, ); }; }; 215F75F92922B1DB009E0E76 /* ARTClientInformation.h in Headers */ = {isa = PBXBuildFile; fileRef = 215F75F62922B1DB009E0E76 /* ARTClientInformation.h */; settings = {ATTRIBUTES = (Public, ); }; }; 215F75FA2922B1DB009E0E76 /* ARTClientInformation.h in Headers */ = {isa = PBXBuildFile; fileRef = 215F75F62922B1DB009E0E76 /* ARTClientInformation.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -1253,6 +1262,9 @@ 2159248A2D636826004A235C /* ARTWrapperSDKProxyPush.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ARTWrapperSDKProxyPush.h; path = include/Ably/ARTWrapperSDKProxyPush.h; sourceTree = ""; }; 2159248E2D636839004A235C /* ARTWrapperSDKProxyPush+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "ARTWrapperSDKProxyPush+Private.h"; path = "PrivateHeaders/Ably/ARTWrapperSDKProxyPush+Private.h"; sourceTree = ""; }; 215924922D636A6E004A235C /* ARTWrapperSDKProxyPush.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ARTWrapperSDKProxyPush.m; sourceTree = ""; }; + 215924962D636AC5004A235C /* ARTWrapperSDKProxyPushAdmin.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ARTWrapperSDKProxyPushAdmin.h; path = include/Ably/ARTWrapperSDKProxyPushAdmin.h; sourceTree = ""; }; + 2159249A2D636AD5004A235C /* ARTWrapperSDKProxyPushAdmin+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "ARTWrapperSDKProxyPushAdmin+Private.h"; path = "PrivateHeaders/Ably/ARTWrapperSDKProxyPushAdmin+Private.h"; sourceTree = ""; }; + 2159249E2D636ADF004A235C /* ARTWrapperSDKProxyPushAdmin.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ARTWrapperSDKProxyPushAdmin.m; sourceTree = ""; }; 215F75F62922B1DB009E0E76 /* ARTClientInformation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ARTClientInformation.h; path = include/Ably/ARTClientInformation.h; sourceTree = ""; }; 215F75F72922B1DB009E0E76 /* ARTClientInformation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ARTClientInformation.m; sourceTree = ""; }; 215F75FE2922B30F009E0E76 /* ClientInformationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClientInformationTests.swift; sourceTree = ""; }; @@ -1682,6 +1694,9 @@ 2159248A2D636826004A235C /* ARTWrapperSDKProxyPush.h */, 2159248E2D636839004A235C /* ARTWrapperSDKProxyPush+Private.h */, 215924922D636A6E004A235C /* ARTWrapperSDKProxyPush.m */, + 215924962D636AC5004A235C /* ARTWrapperSDKProxyPushAdmin.h */, + 2159249A2D636AD5004A235C /* ARTWrapperSDKProxyPushAdmin+Private.h */, + 2159249E2D636ADF004A235C /* ARTWrapperSDKProxyPushAdmin.m */, ); name = "Wrapper SDK Proxy"; sourceTree = ""; @@ -2465,12 +2480,14 @@ 2132C31129D5E4C6000C4355 /* ARTBackoffRetryDelayCalculator.h in Headers */, 2114D42A2D4BC5470032839A /* AblyInternal.h in Headers */, 2114D42B2D4BC5470032839A /* AblyPublic.h in Headers */, + 2159249B2D636AD5004A235C /* ARTWrapperSDKProxyPushAdmin+Private.h in Headers */, D5BB213926AAA60500AA5F3E /* ARTNSError+ARTUtils.h in Headers */, D746AE431BBC5CD0003ECEF8 /* ARTRealtimeChannel+Private.h in Headers */, D746AE251BBB611C003ECEF8 /* ARTChannel+Private.h in Headers */, D5BB210B26AA98A200AA5F3E /* ARTStringifiable+Private.h in Headers */, EB4B1A0C1F2190BB00467F07 /* ARTRestChannels+Private.h in Headers */, D785C4291E549E33008FEC05 /* ARTPushChannelSubscription.h in Headers */, + 215924992D636AC5004A235C /* ARTWrapperSDKProxyPushAdmin.h in Headers */, D7F1D3731BF4DE07001A4B5E /* ARTRestPresence.h in Headers */, D7B17EE31C07208B00A6958E /* ARTConnectionDetails.h in Headers */, D7F2B8B21E42410D00B65151 /* ARTPresenceMessage+Private.h in Headers */, @@ -2569,6 +2586,7 @@ 21AC0CC42D4AA0630030BD23 /* ARTWrapperSDKProxyRealtimeChannel.h in Headers */, 21AC0CC52D4AA0630030BD23 /* ARTWrapperSDKProxyRealtimeChannels.h in Headers */, 213AEA1B2D35A6120067FD5F /* ARTWrapperSDKProxyOptions.h in Headers */, + 2159249D2D636AD5004A235C /* ARTWrapperSDKProxyPushAdmin+Private.h in Headers */, D798556123ECCDAF00946BE2 /* ARTVCDiffDecoder.h in Headers */, 21E1C0E62A0DC47400A5DB65 /* ARTWebSocketFactory.h in Headers */, 2132C32129D5FE74000C4355 /* ARTTypes+Private.h in Headers */, @@ -2682,6 +2700,7 @@ D710D61E21949DEC008F54AD /* ARTFallback+Private.h in Headers */, D5BB211026AA993C00AA5F3E /* ARTNSURL+ARTUtils.h in Headers */, D710D60E21949DDB008F54AD /* ARTPaginatedResult.h in Headers */, + 215924972D636AC5004A235C /* ARTWrapperSDKProxyPushAdmin.h in Headers */, 2114D4302D4BCAE20032839A /* ARTRealtime+WrapperSDKProxy.h in Headers */, D710D4BF21949B6C008F54AD /* ARTNSMutableRequest+ARTRest.h in Headers */, 2147F02E29E583AD0071CB94 /* ARTInternalLogCore.h in Headers */, @@ -2752,6 +2771,7 @@ 21AC0CC22D4AA0630030BD23 /* ARTWrapperSDKProxyRealtimeChannel.h in Headers */, 21AC0CC32D4AA0630030BD23 /* ARTWrapperSDKProxyRealtimeChannels.h in Headers */, 213AEA1A2D35A6120067FD5F /* ARTWrapperSDKProxyOptions.h in Headers */, + 2159249C2D636AD5004A235C /* ARTWrapperSDKProxyPushAdmin+Private.h in Headers */, D710D57221949CBA008F54AD /* ARTPushChannelSubscriptions.h in Headers */, 21E1C0E72A0DC47400A5DB65 /* ARTWebSocketFactory.h in Headers */, 2132C32229D5FE74000C4355 /* ARTTypes+Private.h in Headers */, @@ -2865,6 +2885,7 @@ D710D62A21949DED008F54AD /* ARTFallback+Private.h in Headers */, D710D61821949DDC008F54AD /* ARTPaginatedResult.h in Headers */, D5BB213B26AAA60500AA5F3E /* ARTNSError+ARTUtils.h in Headers */, + 215924982D636AC5004A235C /* ARTWrapperSDKProxyPushAdmin.h in Headers */, 2114D42F2D4BCAE20032839A /* ARTRealtime+WrapperSDKProxy.h in Headers */, D710D4C121949B6D008F54AD /* ARTNSMutableRequest+ARTRest.h in Headers */, 2147F02F29E583AD0071CB94 /* ARTInternalLogCore.h in Headers */, @@ -3257,6 +3278,7 @@ D7B621991E4A762A00684474 /* ARTPushChannel.m in Sources */, EB89D40B1C61C6EA007FA5B7 /* ARTRealtimeChannels.m in Sources */, 217D183B254222F600DFF07E /* ARTSRDelegateController.m in Sources */, + 2159249F2D636ADF004A235C /* ARTWrapperSDKProxyPushAdmin.m in Sources */, D746AE231BBB60EE003ECEF8 /* ARTChannel.m in Sources */, 215924932D636A6E004A235C /* ARTWrapperSDKProxyPush.m in Sources */, D76F153C23DB010C00B5133C /* ARTRealtimeChannelOptions.m in Sources */, @@ -3506,6 +3528,7 @@ D710D62F21949E03008F54AD /* ARTDataQuery.m in Sources */, D710D53121949C54008F54AD /* ARTPush.m in Sources */, 217D1852254222F700DFF07E /* ARTSRDelegateController.m in Sources */, + 215924A02D636ADF004A235C /* ARTWrapperSDKProxyPushAdmin.m in Sources */, D710D5E021949D78008F54AD /* ARTStats.m in Sources */, 215924942D636A6E004A235C /* ARTWrapperSDKProxyPush.m in Sources */, D76F153F23DB013000B5133C /* ARTRealtimeChannelOptions.m in Sources */, @@ -3635,6 +3658,7 @@ D710D54321949C55008F54AD /* ARTPush.m in Sources */, 217D1869254222FA00DFF07E /* ARTSRDelegateController.m in Sources */, D710D60621949D79008F54AD /* ARTStats.m in Sources */, + 215924A12D636ADF004A235C /* ARTWrapperSDKProxyPushAdmin.m in Sources */, D76F154023DB013000B5133C /* ARTRealtimeChannelOptions.m in Sources */, 215924952D636A6E004A235C /* ARTWrapperSDKProxyPush.m in Sources */, D710D50121949C0E008F54AD /* ARTQueuedMessage.m in Sources */, diff --git a/Source/ARTWrapperSDKProxyPush.m b/Source/ARTWrapperSDKProxyPush.m index 9e64dd00b..88b19fb40 100644 --- a/Source/ARTWrapperSDKProxyPush.m +++ b/Source/ARTWrapperSDKProxyPush.m @@ -1,4 +1,5 @@ #import "ARTWrapperSDKProxyPush+Private.h" +#import "ARTWrapperSDKProxyPushAdmin+Private.h" NS_ASSUME_NONNULL_BEGIN @@ -17,15 +18,13 @@ - (instancetype)initWithPush:(ARTPush *)push proxyOptions:(ARTWrapperSDKProxyOpt if (self = [super init]) { _underlyingPush = push; _proxyOptions = proxyOptions; + _admin = [[ARTWrapperSDKProxyPushAdmin alloc] initWithPushAdmin:push.admin + proxyOptions:proxyOptions]; } return self; } -- (ARTPushAdmin *)admin { - return self.underlyingPush.admin; -} - #if TARGET_OS_IOS - (void)activate { diff --git a/Source/ARTWrapperSDKProxyPushAdmin.m b/Source/ARTWrapperSDKProxyPushAdmin.m new file mode 100644 index 000000000..c7fde8920 --- /dev/null +++ b/Source/ARTWrapperSDKProxyPushAdmin.m @@ -0,0 +1,39 @@ +#import "ARTWrapperSDKProxyPushAdmin+Private.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface ARTWrapperSDKProxyPushAdmin () + +@property (nonatomic, readonly) ARTPushAdmin *underlyingPushAdmin; +@property (nonatomic, readonly) ARTWrapperSDKProxyOptions *proxyOptions; + +@end + +NS_ASSUME_NONNULL_END + +@implementation ARTWrapperSDKProxyPushAdmin + +- (instancetype)initWithPushAdmin:(ARTPushAdmin *)pushAdmin proxyOptions:(ARTWrapperSDKProxyOptions *)proxyOptions { + if (self = [super init]) { + _underlyingPushAdmin = pushAdmin; + _proxyOptions = proxyOptions; + } + + return self; +} + +- (ARTPushDeviceRegistrations *)deviceRegistrations { + return self.underlyingPushAdmin.deviceRegistrations; +} + +- (ARTPushChannelSubscriptions *)channelSubscriptions { + return self.underlyingPushAdmin.channelSubscriptions; +} + +- (void)publish:(nonnull ARTPushRecipient *)recipient data:(nonnull ARTJsonObject *)data callback:(nullable ARTCallback)callback { + [self.underlyingPushAdmin publish:recipient + data:data + callback:callback]; +} + +@end diff --git a/Source/Ably.modulemap b/Source/Ably.modulemap index 8a46bb864..329b9f2b5 100644 --- a/Source/Ably.modulemap +++ b/Source/Ably.modulemap @@ -117,5 +117,6 @@ framework module Ably { header "ARTWrapperSDKProxyRealtimeChannel+Private.h" header "ARTChannel.h" header "ARTWrapperSDKProxyPush+Private.h" + header "ARTWrapperSDKProxyPushAdmin+Private.h" } } diff --git a/Source/PrivateHeaders/Ably/ARTWrapperSDKProxyPushAdmin+Private.h b/Source/PrivateHeaders/Ably/ARTWrapperSDKProxyPushAdmin+Private.h new file mode 100644 index 000000000..b3427d600 --- /dev/null +++ b/Source/PrivateHeaders/Ably/ARTWrapperSDKProxyPushAdmin+Private.h @@ -0,0 +1,14 @@ +#import + +@class ARTWrapperSDKProxyOptions; + +NS_ASSUME_NONNULL_BEGIN + +@interface ARTWrapperSDKProxyPushAdmin () + +- (instancetype)initWithPushAdmin:(ARTPushAdmin *)pushAdmin + proxyOptions:(ARTWrapperSDKProxyOptions *)proxyOptions NS_DESIGNATED_INITIALIZER; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Source/include/Ably.modulemap b/Source/include/Ably.modulemap index 5b93f3d76..4432ce740 100644 --- a/Source/include/Ably.modulemap +++ b/Source/include/Ably.modulemap @@ -115,5 +115,6 @@ framework module Ably { header "Ably/ARTWrapperSDKProxyRealtimeChannel+Private.h" header "Ably/ARTChannel.h" header "Ably/ARTWrapperSDKProxyPush+Private.h" + header "Ably/ARTWrapperSDKProxyPushAdmin+Private.h" } } diff --git a/Source/include/Ably/ARTWrapperSDKProxyPush.h b/Source/include/Ably/ARTWrapperSDKProxyPush.h index deb7abc8a..483a47972 100644 --- a/Source/include/Ably/ARTWrapperSDKProxyPush.h +++ b/Source/include/Ably/ARTWrapperSDKProxyPush.h @@ -1,7 +1,7 @@ #import #import -@class ARTPushAdmin; +@class ARTWrapperSDKProxyPushAdmin; NS_ASSUME_NONNULL_BEGIN @@ -15,7 +15,7 @@ NS_SWIFT_SENDABLE - (instancetype)init NS_UNAVAILABLE; -@property (readonly) ARTPushAdmin *admin; +@property (readonly) ARTWrapperSDKProxyPushAdmin *admin; @end diff --git a/Source/include/Ably/ARTWrapperSDKProxyPushAdmin.h b/Source/include/Ably/ARTWrapperSDKProxyPushAdmin.h new file mode 100644 index 000000000..1b30ddebf --- /dev/null +++ b/Source/include/Ably/ARTWrapperSDKProxyPushAdmin.h @@ -0,0 +1,24 @@ +#import +#import + +@class ARTPushDeviceRegistrations; +@class ARTPushChannelSubscriptions; + +NS_ASSUME_NONNULL_BEGIN + +/** + * An object which wraps an instance of `ARTPushAdmin` and provides a similar API. It allows Ably-authored wrapper SDKs to send analytics information so that Ably can track the usage of the wrapper SDK. + * + * - Important: This class should only be used by Ably-authored SDKs. + */ +NS_SWIFT_SENDABLE +@interface ARTWrapperSDKProxyPushAdmin : NSObject + +- (instancetype)init NS_UNAVAILABLE; + +@property (nonatomic, readonly) ARTPushDeviceRegistrations *deviceRegistrations; +@property (nonatomic, readonly) ARTPushChannelSubscriptions *channelSubscriptions; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Source/include/Ably/AblyInternal.h b/Source/include/Ably/AblyInternal.h index 6aa845c15..5e5a1ac5e 100644 --- a/Source/include/Ably/AblyInternal.h +++ b/Source/include/Ably/AblyInternal.h @@ -6,3 +6,4 @@ #import #import #import +#import From ded95bc6a0420193d023ba08ca99e269e8a523f1 Mon Sep 17 00:00:00 2001 From: Lawrence Forooghian Date: Thu, 13 Feb 2025 10:11:20 -0300 Subject: [PATCH 09/16] Insert wrapper SDK agents in push admin requests As in b006650. --- Source/ARTPushAdmin.m | 6 +++--- Source/ARTWrapperSDKProxyPushAdmin.m | 9 ++++++--- Source/PrivateHeaders/Ably/ARTPushAdmin+Private.h | 2 +- Test/Tests/WrapperSDKProxyTests.swift | 13 +++++++++++++ 4 files changed, 23 insertions(+), 7 deletions(-) diff --git a/Source/ARTPushAdmin.m b/Source/ARTPushAdmin.m index edac6b252..9d17ade0d 100644 --- a/Source/ARTPushAdmin.m +++ b/Source/ARTPushAdmin.m @@ -21,7 +21,7 @@ - (instancetype)initWithInternal:(ARTPushAdminInternal *)internal queuedDealloc: } - (void)publish:(ARTPushRecipient *)recipient data:(ARTJsonObject *)data callback:(nullable ARTCallback)callback { - [_internal publish:recipient data:data callback:callback]; + [_internal publish:recipient data:data wrapperSDKAgents:nil callback:callback]; } - (ARTPushDeviceRegistrations *)deviceRegistrations { @@ -53,7 +53,7 @@ - (instancetype)initWithRest:(ARTRestInternal *)rest logger:(ARTInternalLog *)lo return self; } -- (void)publish:(ARTPushRecipient *)recipient data:(ARTJsonObject *)data callback:(nullable ARTCallback)callback { +- (void)publish:(ARTPushRecipient *)recipient data:(ARTJsonObject *)data wrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents callback:(nullable ARTCallback)callback { if (callback) { ARTCallback userCallback = callback; callback = ^(ARTErrorInfo *error) { @@ -83,7 +83,7 @@ - (void)publish:(ARTPushRecipient *)recipient data:(ARTJsonObject *)data callbac [request setValue:[[self->_rest defaultEncoder] mimeType] forHTTPHeaderField:@"Content-Type"]; ARTLogDebug(self->_logger, @"push notification to a single device %@", request); - [self->_rest executeRequest:request withAuthOption:ARTAuthenticationOn wrapperSDKAgents:nil completion:^(NSHTTPURLResponse *response, NSData *data, NSError *error) { + [self->_rest executeRequest:request withAuthOption:ARTAuthenticationOn wrapperSDKAgents:wrapperSDKAgents completion:^(NSHTTPURLResponse *response, NSData *data, NSError *error) { if (error) { ARTLogError(self->_logger, @"%@: push notification to a single device failed (%@)", NSStringFromClass(self.class), error.localizedDescription); if (callback) callback([ARTErrorInfo createFromNSError:error]); diff --git a/Source/ARTWrapperSDKProxyPushAdmin.m b/Source/ARTWrapperSDKProxyPushAdmin.m index c7fde8920..5f5cc3b8e 100644 --- a/Source/ARTWrapperSDKProxyPushAdmin.m +++ b/Source/ARTWrapperSDKProxyPushAdmin.m @@ -1,4 +1,6 @@ #import "ARTWrapperSDKProxyPushAdmin+Private.h" +#import "ARTPushAdmin+Private.h" +#import "ARTWrapperSDKProxyOptions.h" NS_ASSUME_NONNULL_BEGIN @@ -31,9 +33,10 @@ - (ARTPushChannelSubscriptions *)channelSubscriptions { } - (void)publish:(nonnull ARTPushRecipient *)recipient data:(nonnull ARTJsonObject *)data callback:(nullable ARTCallback)callback { - [self.underlyingPushAdmin publish:recipient - data:data - callback:callback]; + [self.underlyingPushAdmin.internal publish:recipient + data:data + wrapperSDKAgents:self.proxyOptions.agents + callback:callback]; } @end diff --git a/Source/PrivateHeaders/Ably/ARTPushAdmin+Private.h b/Source/PrivateHeaders/Ably/ARTPushAdmin+Private.h index 0179c5e0c..b69b5b4cd 100644 --- a/Source/PrivateHeaders/Ably/ARTPushAdmin+Private.h +++ b/Source/PrivateHeaders/Ably/ARTPushAdmin+Private.h @@ -14,7 +14,7 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)initWithRest:(ARTRestInternal *)rest logger:(ARTInternalLog *)logger; -- (void)publish:(ARTPushRecipient *)recipient data:(ARTJsonObject *)data callback:(nullable ARTCallback)callback; +- (void)publish:(ARTPushRecipient *)recipient data:(ARTJsonObject *)data wrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents callback:(nullable ARTCallback)callback; @end diff --git a/Test/Tests/WrapperSDKProxyTests.swift b/Test/Tests/WrapperSDKProxyTests.swift index 36657425b..3862a36bb 100644 --- a/Test/Tests/WrapperSDKProxyTests.swift +++ b/Test/Tests/WrapperSDKProxyTests.swift @@ -430,6 +430,19 @@ class WrapperSDKProxyTests: XCTestCase { } } + func test_pushAdmin_addsWrapperSDKAgentToRequests() throws { + let test = Test() + + try parameterizedTest_addsWrapperSDKAgentToRequests(test: test) { proxyClient in + waitUntil(timeout: testTimeout) { done in + proxyClient.push.admin.publish(["clientId" : "foo"], data: ["notification" : ["title" : "Welcome"]]) { error in + XCTAssertNil(error) + done() + } + } + } + } + // MARK: - `agent` channel param private func parameterizedTest_checkAttachProtocolMessage( From 49a4628d09b410a14c26fec76552301ca0fbb4ec Mon Sep 17 00:00:00 2001 From: Lawrence Forooghian Date: Wed, 12 Feb 2025 16:53:56 -0300 Subject: [PATCH 10/16] Create wrapper SDK proxy channel subscriptions and device registrations classes As in 4daf4ba. --- Ably.xcodeproj/project.pbxproj | 48 ++++++++++++++++++ Source/ARTWrapperSDKProxyPushAdmin.m | 14 +++--- ...TWrapperSDKProxyPushChannelSubscriptions.m | 49 ++++++++++++++++++ ...RTWrapperSDKProxyPushDeviceRegistrations.m | 50 +++++++++++++++++++ Source/Ably.modulemap | 2 + ...SDKProxyPushChannelSubscriptions+Private.h | 14 ++++++ ...rSDKProxyPushDeviceRegistrations+Private.h | 14 ++++++ Source/include/Ably.modulemap | 2 + .../Ably/ARTWrapperSDKProxyPushAdmin.h | 8 +-- ...TWrapperSDKProxyPushChannelSubscriptions.h | 18 +++++++ ...RTWrapperSDKProxyPushDeviceRegistrations.h | 18 +++++++ Source/include/Ably/AblyInternal.h | 2 + 12 files changed, 227 insertions(+), 12 deletions(-) create mode 100644 Source/ARTWrapperSDKProxyPushChannelSubscriptions.m create mode 100644 Source/ARTWrapperSDKProxyPushDeviceRegistrations.m create mode 100644 Source/PrivateHeaders/Ably/ARTWrapperSDKProxyPushChannelSubscriptions+Private.h create mode 100644 Source/PrivateHeaders/Ably/ARTWrapperSDKProxyPushDeviceRegistrations+Private.h create mode 100644 Source/include/Ably/ARTWrapperSDKProxyPushChannelSubscriptions.h create mode 100644 Source/include/Ably/ARTWrapperSDKProxyPushDeviceRegistrations.h diff --git a/Ably.xcodeproj/project.pbxproj b/Ably.xcodeproj/project.pbxproj index 074d6632b..d246a911e 100644 --- a/Ably.xcodeproj/project.pbxproj +++ b/Ably.xcodeproj/project.pbxproj @@ -226,6 +226,24 @@ 2159249F2D636ADF004A235C /* ARTWrapperSDKProxyPushAdmin.m in Sources */ = {isa = PBXBuildFile; fileRef = 2159249E2D636ADF004A235C /* ARTWrapperSDKProxyPushAdmin.m */; }; 215924A02D636ADF004A235C /* ARTWrapperSDKProxyPushAdmin.m in Sources */ = {isa = PBXBuildFile; fileRef = 2159249E2D636ADF004A235C /* ARTWrapperSDKProxyPushAdmin.m */; }; 215924A12D636ADF004A235C /* ARTWrapperSDKProxyPushAdmin.m in Sources */ = {isa = PBXBuildFile; fileRef = 2159249E2D636ADF004A235C /* ARTWrapperSDKProxyPushAdmin.m */; }; + 215924A42D636B5C004A235C /* ARTWrapperSDKProxyPushDeviceRegistrations.h in Headers */ = {isa = PBXBuildFile; fileRef = 215924A32D636B5C004A235C /* ARTWrapperSDKProxyPushDeviceRegistrations.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 215924A52D636B5C004A235C /* ARTWrapperSDKProxyPushChannelSubscriptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 215924A22D636B5C004A235C /* ARTWrapperSDKProxyPushChannelSubscriptions.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 215924A62D636B5C004A235C /* ARTWrapperSDKProxyPushDeviceRegistrations.h in Headers */ = {isa = PBXBuildFile; fileRef = 215924A32D636B5C004A235C /* ARTWrapperSDKProxyPushDeviceRegistrations.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 215924A72D636B5C004A235C /* ARTWrapperSDKProxyPushChannelSubscriptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 215924A22D636B5C004A235C /* ARTWrapperSDKProxyPushChannelSubscriptions.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 215924A82D636B5C004A235C /* ARTWrapperSDKProxyPushDeviceRegistrations.h in Headers */ = {isa = PBXBuildFile; fileRef = 215924A32D636B5C004A235C /* ARTWrapperSDKProxyPushDeviceRegistrations.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 215924A92D636B5C004A235C /* ARTWrapperSDKProxyPushChannelSubscriptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 215924A22D636B5C004A235C /* ARTWrapperSDKProxyPushChannelSubscriptions.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 215924AC2D636B6B004A235C /* ARTWrapperSDKProxyPushDeviceRegistrations+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 215924AB2D636B6B004A235C /* ARTWrapperSDKProxyPushDeviceRegistrations+Private.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 215924AD2D636B6B004A235C /* ARTWrapperSDKProxyPushChannelSubscriptions+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 215924AA2D636B6B004A235C /* ARTWrapperSDKProxyPushChannelSubscriptions+Private.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 215924AE2D636B6B004A235C /* ARTWrapperSDKProxyPushDeviceRegistrations+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 215924AB2D636B6B004A235C /* ARTWrapperSDKProxyPushDeviceRegistrations+Private.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 215924AF2D636B6B004A235C /* ARTWrapperSDKProxyPushChannelSubscriptions+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 215924AA2D636B6B004A235C /* ARTWrapperSDKProxyPushChannelSubscriptions+Private.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 215924B02D636B6B004A235C /* ARTWrapperSDKProxyPushDeviceRegistrations+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 215924AB2D636B6B004A235C /* ARTWrapperSDKProxyPushDeviceRegistrations+Private.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 215924B12D636B6B004A235C /* ARTWrapperSDKProxyPushChannelSubscriptions+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 215924AA2D636B6B004A235C /* ARTWrapperSDKProxyPushChannelSubscriptions+Private.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 215924B42D636B89004A235C /* ARTWrapperSDKProxyPushChannelSubscriptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 215924B22D636B89004A235C /* ARTWrapperSDKProxyPushChannelSubscriptions.m */; }; + 215924B52D636B89004A235C /* ARTWrapperSDKProxyPushDeviceRegistrations.m in Sources */ = {isa = PBXBuildFile; fileRef = 215924B32D636B89004A235C /* ARTWrapperSDKProxyPushDeviceRegistrations.m */; }; + 215924B62D636B89004A235C /* ARTWrapperSDKProxyPushChannelSubscriptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 215924B22D636B89004A235C /* ARTWrapperSDKProxyPushChannelSubscriptions.m */; }; + 215924B72D636B89004A235C /* ARTWrapperSDKProxyPushDeviceRegistrations.m in Sources */ = {isa = PBXBuildFile; fileRef = 215924B32D636B89004A235C /* ARTWrapperSDKProxyPushDeviceRegistrations.m */; }; + 215924B82D636B89004A235C /* ARTWrapperSDKProxyPushChannelSubscriptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 215924B22D636B89004A235C /* ARTWrapperSDKProxyPushChannelSubscriptions.m */; }; + 215924B92D636B89004A235C /* ARTWrapperSDKProxyPushDeviceRegistrations.m in Sources */ = {isa = PBXBuildFile; fileRef = 215924B32D636B89004A235C /* ARTWrapperSDKProxyPushDeviceRegistrations.m */; }; 215F75F82922B1DB009E0E76 /* ARTClientInformation.h in Headers */ = {isa = PBXBuildFile; fileRef = 215F75F62922B1DB009E0E76 /* ARTClientInformation.h */; settings = {ATTRIBUTES = (Public, ); }; }; 215F75F92922B1DB009E0E76 /* ARTClientInformation.h in Headers */ = {isa = PBXBuildFile; fileRef = 215F75F62922B1DB009E0E76 /* ARTClientInformation.h */; settings = {ATTRIBUTES = (Public, ); }; }; 215F75FA2922B1DB009E0E76 /* ARTClientInformation.h in Headers */ = {isa = PBXBuildFile; fileRef = 215F75F62922B1DB009E0E76 /* ARTClientInformation.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -1265,6 +1283,12 @@ 215924962D636AC5004A235C /* ARTWrapperSDKProxyPushAdmin.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ARTWrapperSDKProxyPushAdmin.h; path = include/Ably/ARTWrapperSDKProxyPushAdmin.h; sourceTree = ""; }; 2159249A2D636AD5004A235C /* ARTWrapperSDKProxyPushAdmin+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "ARTWrapperSDKProxyPushAdmin+Private.h"; path = "PrivateHeaders/Ably/ARTWrapperSDKProxyPushAdmin+Private.h"; sourceTree = ""; }; 2159249E2D636ADF004A235C /* ARTWrapperSDKProxyPushAdmin.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ARTWrapperSDKProxyPushAdmin.m; sourceTree = ""; }; + 215924A22D636B5C004A235C /* ARTWrapperSDKProxyPushChannelSubscriptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ARTWrapperSDKProxyPushChannelSubscriptions.h; path = include/Ably/ARTWrapperSDKProxyPushChannelSubscriptions.h; sourceTree = ""; }; + 215924A32D636B5C004A235C /* ARTWrapperSDKProxyPushDeviceRegistrations.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ARTWrapperSDKProxyPushDeviceRegistrations.h; path = include/Ably/ARTWrapperSDKProxyPushDeviceRegistrations.h; sourceTree = ""; }; + 215924AA2D636B6B004A235C /* ARTWrapperSDKProxyPushChannelSubscriptions+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "ARTWrapperSDKProxyPushChannelSubscriptions+Private.h"; path = "PrivateHeaders/Ably/ARTWrapperSDKProxyPushChannelSubscriptions+Private.h"; sourceTree = ""; }; + 215924AB2D636B6B004A235C /* ARTWrapperSDKProxyPushDeviceRegistrations+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "ARTWrapperSDKProxyPushDeviceRegistrations+Private.h"; path = "PrivateHeaders/Ably/ARTWrapperSDKProxyPushDeviceRegistrations+Private.h"; sourceTree = ""; }; + 215924B22D636B89004A235C /* ARTWrapperSDKProxyPushChannelSubscriptions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ARTWrapperSDKProxyPushChannelSubscriptions.m; sourceTree = ""; }; + 215924B32D636B89004A235C /* ARTWrapperSDKProxyPushDeviceRegistrations.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ARTWrapperSDKProxyPushDeviceRegistrations.m; sourceTree = ""; }; 215F75F62922B1DB009E0E76 /* ARTClientInformation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ARTClientInformation.h; path = include/Ably/ARTClientInformation.h; sourceTree = ""; }; 215F75F72922B1DB009E0E76 /* ARTClientInformation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ARTClientInformation.m; sourceTree = ""; }; 215F75FE2922B30F009E0E76 /* ClientInformationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClientInformationTests.swift; sourceTree = ""; }; @@ -1697,6 +1721,12 @@ 215924962D636AC5004A235C /* ARTWrapperSDKProxyPushAdmin.h */, 2159249A2D636AD5004A235C /* ARTWrapperSDKProxyPushAdmin+Private.h */, 2159249E2D636ADF004A235C /* ARTWrapperSDKProxyPushAdmin.m */, + 215924A32D636B5C004A235C /* ARTWrapperSDKProxyPushDeviceRegistrations.h */, + 215924AB2D636B6B004A235C /* ARTWrapperSDKProxyPushDeviceRegistrations+Private.h */, + 215924B32D636B89004A235C /* ARTWrapperSDKProxyPushDeviceRegistrations.m */, + 215924A22D636B5C004A235C /* ARTWrapperSDKProxyPushChannelSubscriptions.h */, + 215924AA2D636B6B004A235C /* ARTWrapperSDKProxyPushChannelSubscriptions+Private.h */, + 215924B22D636B89004A235C /* ARTWrapperSDKProxyPushChannelSubscriptions.m */, ); name = "Wrapper SDK Proxy"; sourceTree = ""; @@ -2410,6 +2440,8 @@ EB9C530B1CD7BEB100.8.557 /* ARTJsonLikeEncoder.h in Headers */, D74CBC0E212F076000D090E4 /* ARTConstants.h in Headers */, D7CEF12D1C8D821D004FB242 /* ARTRealtimeChannels+Private.h in Headers */, + 215924A42D636B5C004A235C /* ARTWrapperSDKProxyPushDeviceRegistrations.h in Headers */, + 215924A52D636B5C004A235C /* ARTWrapperSDKProxyPushChannelSubscriptions.h in Headers */, EB89D4011C61C10E007FA5B7 /* ARTChannels+Private.h in Headers */, D74CBC03212EB58700D090E4 /* ARTNSHTTPURLResponse+ARTPaginated.h in Headers */, 1CD8DC9F1B1C7315007EAF36 /* ARTDefault.h in Headers */, @@ -2510,6 +2542,8 @@ 96A507A51A377DE90077CDF8 /* ARTNSDictionary+ARTDictionaryUtil.h in Headers */, D75A3F1B1DDE5B62002A4AAD /* ARTGCD.h in Headers */, D3AD0EBD215E2FB000312105 /* ARTNSString+ARTUtil.h in Headers */, + 215924B02D636B6B004A235C /* ARTWrapperSDKProxyPushDeviceRegistrations+Private.h in Headers */, + 215924B12D636B6B004A235C /* ARTWrapperSDKProxyPushChannelSubscriptions+Private.h in Headers */, EB2D85011CD769C800F23CDA /* ARTOSReachability.h in Headers */, 21E1C0E52A0DC47400A5DB65 /* ARTWebSocketFactory.h in Headers */, EB1B541522FB1CE1006A59AC /* ARTPushDeviceRegistrations+Private.h in Headers */, @@ -2670,6 +2704,8 @@ D710D58321949D28008F54AD /* ARTTokenDetails.h in Headers */, D710D54C21949C66008F54AD /* ARTPush+Private.h in Headers */, D710D68A21949EDA008F54AD /* ARTNSDate+ARTUtil.h in Headers */, + 215924A62D636B5C004A235C /* ARTWrapperSDKProxyPushDeviceRegistrations.h in Headers */, + 215924A72D636B5C004A235C /* ARTWrapperSDKProxyPushChannelSubscriptions.h in Headers */, D710D4D721949BF9008F54AD /* ARTConnectionDetails.h in Headers */, D710D4DB21949BF9008F54AD /* ARTRealtimeChannels.h in Headers */, D710D61021949DDB008F54AD /* ARTFallback.h in Headers */, @@ -2701,6 +2737,8 @@ D5BB211026AA993C00AA5F3E /* ARTNSURL+ARTUtils.h in Headers */, D710D60E21949DDB008F54AD /* ARTPaginatedResult.h in Headers */, 215924972D636AC5004A235C /* ARTWrapperSDKProxyPushAdmin.h in Headers */, + 215924AE2D636B6B004A235C /* ARTWrapperSDKProxyPushDeviceRegistrations+Private.h in Headers */, + 215924AF2D636B6B004A235C /* ARTWrapperSDKProxyPushChannelSubscriptions+Private.h in Headers */, 2114D4302D4BCAE20032839A /* ARTRealtime+WrapperSDKProxy.h in Headers */, D710D4BF21949B6C008F54AD /* ARTNSMutableRequest+ARTRest.h in Headers */, 2147F02E29E583AD0071CB94 /* ARTInternalLogCore.h in Headers */, @@ -2855,6 +2893,8 @@ D710D5A921949D2A008F54AD /* ARTTokenDetails.h in Headers */, D710D55221949C67008F54AD /* ARTPush+Private.h in Headers */, D710D68C21949EDB008F54AD /* ARTNSDate+ARTUtil.h in Headers */, + 215924A82D636B5C004A235C /* ARTWrapperSDKProxyPushDeviceRegistrations.h in Headers */, + 215924A92D636B5C004A235C /* ARTWrapperSDKProxyPushChannelSubscriptions.h in Headers */, D710D4E721949BFB008F54AD /* ARTConnectionDetails.h in Headers */, D710D4EB21949BFB008F54AD /* ARTRealtimeChannels.h in Headers */, D710D61A21949DDC008F54AD /* ARTFallback.h in Headers */, @@ -2886,6 +2926,8 @@ D710D61821949DDC008F54AD /* ARTPaginatedResult.h in Headers */, D5BB213B26AAA60500AA5F3E /* ARTNSError+ARTUtils.h in Headers */, 215924982D636AC5004A235C /* ARTWrapperSDKProxyPushAdmin.h in Headers */, + 215924AC2D636B6B004A235C /* ARTWrapperSDKProxyPushDeviceRegistrations+Private.h in Headers */, + 215924AD2D636B6B004A235C /* ARTWrapperSDKProxyPushChannelSubscriptions+Private.h in Headers */, 2114D42F2D4BCAE20032839A /* ARTRealtime+WrapperSDKProxy.h in Headers */, D710D4C121949B6D008F54AD /* ARTNSMutableRequest+ARTRest.h in Headers */, 2147F02F29E583AD0071CB94 /* ARTInternalLogCore.h in Headers */, @@ -3334,6 +3376,8 @@ 961343D91A42E0B7006DC822 /* ARTClientOptions.m in Sources */, 96BF615F1A35C1C8004CF2B3 /* ARTTypes.m in Sources */, 217D1838254222F600DFF07E /* NSRunLoop+ARTSRWebSocket.m in Sources */, + 215924B82D636B89004A235C /* ARTWrapperSDKProxyPushChannelSubscriptions.m in Sources */, + 215924B92D636B89004A235C /* ARTWrapperSDKProxyPushDeviceRegistrations.m in Sources */, D7D8F82E1BC2C706009718F2 /* ARTTokenParams.m in Sources */, D746AE411BBC5B14003ECEF8 /* ARTEventEmitter.m in Sources */, 2104EFA82A4CC30C00CC1184 /* ARTAttachRetryState.m in Sources */, @@ -3584,6 +3628,8 @@ D710D55E21949C97008F54AD /* ARTPushActivationStateMachine.m in Sources */, D710D49C21949ACA008F54AD /* ARTNSMutableRequest+ARTRest.m in Sources */, 217D184F254222F700DFF07E /* NSRunLoop+ARTSRWebSocket.m in Sources */, + 215924B42D636B89004A235C /* ARTWrapperSDKProxyPushChannelSubscriptions.m in Sources */, + 215924B52D636B89004A235C /* ARTWrapperSDKProxyPushDeviceRegistrations.m in Sources */, D710D66C21949E78008F54AD /* ARTMsgPackEncoder.m in Sources */, D710D48621949A5B008F54AD /* ARTDefault.m in Sources */, 2104EFA92A4CC30C00CC1184 /* ARTAttachRetryState.m in Sources */, @@ -3714,6 +3760,8 @@ D710D56421949C98008F54AD /* ARTPushActivationStateMachine.m in Sources */, D710D4A621949ACB008F54AD /* ARTNSMutableRequest+ARTRest.m in Sources */, 217D1866254222FA00DFF07E /* NSRunLoop+ARTSRWebSocket.m in Sources */, + 215924B62D636B89004A235C /* ARTWrapperSDKProxyPushChannelSubscriptions.m in Sources */, + 215924B72D636B89004A235C /* ARTWrapperSDKProxyPushDeviceRegistrations.m in Sources */, D710D65221949E77008F54AD /* ARTMsgPackEncoder.m in Sources */, D710D48821949A5C008F54AD /* ARTDefault.m in Sources */, 2104EFAA2A4CC30C00CC1184 /* ARTAttachRetryState.m in Sources */, diff --git a/Source/ARTWrapperSDKProxyPushAdmin.m b/Source/ARTWrapperSDKProxyPushAdmin.m index 5f5cc3b8e..7b3db5736 100644 --- a/Source/ARTWrapperSDKProxyPushAdmin.m +++ b/Source/ARTWrapperSDKProxyPushAdmin.m @@ -1,6 +1,8 @@ #import "ARTWrapperSDKProxyPushAdmin+Private.h" #import "ARTPushAdmin+Private.h" #import "ARTWrapperSDKProxyOptions.h" +#import "ARTWrapperSDKProxyPushDeviceRegistrations+Private.h" +#import "ARTWrapperSDKProxyPushChannelSubscriptions+Private.h" NS_ASSUME_NONNULL_BEGIN @@ -19,19 +21,15 @@ - (instancetype)initWithPushAdmin:(ARTPushAdmin *)pushAdmin proxyOptions:(ARTWra if (self = [super init]) { _underlyingPushAdmin = pushAdmin; _proxyOptions = proxyOptions; + _deviceRegistrations = [[ARTWrapperSDKProxyPushDeviceRegistrations alloc] initWithPushDeviceRegistrations:pushAdmin.deviceRegistrations + proxyOptions:proxyOptions]; + _channelSubscriptions = [[ARTWrapperSDKProxyPushChannelSubscriptions alloc] initWithPushChannelSubscriptions:pushAdmin.channelSubscriptions + proxyOptions:proxyOptions]; } return self; } -- (ARTPushDeviceRegistrations *)deviceRegistrations { - return self.underlyingPushAdmin.deviceRegistrations; -} - -- (ARTPushChannelSubscriptions *)channelSubscriptions { - return self.underlyingPushAdmin.channelSubscriptions; -} - - (void)publish:(nonnull ARTPushRecipient *)recipient data:(nonnull ARTJsonObject *)data callback:(nullable ARTCallback)callback { [self.underlyingPushAdmin.internal publish:recipient data:data diff --git a/Source/ARTWrapperSDKProxyPushChannelSubscriptions.m b/Source/ARTWrapperSDKProxyPushChannelSubscriptions.m new file mode 100644 index 000000000..06ed799bc --- /dev/null +++ b/Source/ARTWrapperSDKProxyPushChannelSubscriptions.m @@ -0,0 +1,49 @@ +#import "ARTWrapperSDKProxyPushChannelSubscriptions+Private.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface ARTWrapperSDKProxyPushChannelSubscriptions () + +@property (nonatomic, readonly) ARTPushChannelSubscriptions *underlyingPushChannelSubscriptions; +@property (nonatomic, readonly) ARTWrapperSDKProxyOptions *proxyOptions; + +@end + +NS_ASSUME_NONNULL_END + +@implementation ARTWrapperSDKProxyPushChannelSubscriptions + +- (instancetype)initWithPushChannelSubscriptions:(ARTPushChannelSubscriptions *)pushChannelSubscriptions proxyOptions:(ARTWrapperSDKProxyOptions *)proxyOptions { + if (self = [super init]) { + _underlyingPushChannelSubscriptions = pushChannelSubscriptions; + _proxyOptions = proxyOptions; + } + + return self; +} + +- (void)list:(nonnull NSStringDictionary *)params callback:(nonnull ARTPaginatedPushChannelCallback)callback { + [self.underlyingPushChannelSubscriptions list:params + callback:callback]; +} + +- (void)listChannels:(nonnull ARTPaginatedTextCallback)callback { + [self.underlyingPushChannelSubscriptions listChannels:callback]; +} + +- (void)remove:(nonnull ARTPushChannelSubscription *)subscription callback:(nonnull ARTCallback)callback { + [self.underlyingPushChannelSubscriptions remove:subscription + callback:callback]; +} + +- (void)removeWhere:(nonnull NSStringDictionary *)params callback:(nonnull ARTCallback)callback { + [self.underlyingPushChannelSubscriptions removeWhere:params + callback:callback]; +} + +- (void)save:(nonnull ARTPushChannelSubscription *)channelSubscription callback:(nonnull ARTCallback)callback { + [self.underlyingPushChannelSubscriptions save:channelSubscription + callback:callback]; +} + +@end diff --git a/Source/ARTWrapperSDKProxyPushDeviceRegistrations.m b/Source/ARTWrapperSDKProxyPushDeviceRegistrations.m new file mode 100644 index 000000000..cae14e242 --- /dev/null +++ b/Source/ARTWrapperSDKProxyPushDeviceRegistrations.m @@ -0,0 +1,50 @@ +#import "ARTWrapperSDKProxyPushDeviceRegistrations+Private.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface ARTWrapperSDKProxyPushDeviceRegistrations () + +@property (nonatomic, readonly) ARTPushDeviceRegistrations *underlyingPushDeviceRegistrations; +@property (nonatomic, readonly) ARTWrapperSDKProxyOptions *proxyOptions; + +@end + +NS_ASSUME_NONNULL_END + +@implementation ARTWrapperSDKProxyPushDeviceRegistrations + +- (instancetype)initWithPushDeviceRegistrations:(ARTPushDeviceRegistrations *)pushDeviceRegistrations proxyOptions:(ARTWrapperSDKProxyOptions *)proxyOptions { + if (self = [super init]) { + _underlyingPushDeviceRegistrations = pushDeviceRegistrations; + _proxyOptions = proxyOptions; + } + + return self; +} + +- (void)get:(nonnull ARTDeviceId *)deviceId callback:(nonnull void (^)(ARTDeviceDetails * _Nullable, ARTErrorInfo * _Nullable))callback { + [self.underlyingPushDeviceRegistrations get:deviceId + callback:callback]; +} + +- (void)list:(nonnull NSStringDictionary *)params callback:(nonnull ARTPaginatedDeviceDetailsCallback)callback { + [self.underlyingPushDeviceRegistrations list:params + callback:callback]; +} + +- (void)remove:(nonnull NSString *)deviceId callback:(nonnull ARTCallback)callback { + [self.underlyingPushDeviceRegistrations remove:deviceId + callback:callback]; +} + +- (void)removeWhere:(nonnull NSStringDictionary *)params callback:(nonnull ARTCallback)callback { + [self.underlyingPushDeviceRegistrations removeWhere:params + callback:callback]; +} + +- (void)save:(nonnull ARTDeviceDetails *)deviceDetails callback:(nonnull ARTCallback)callback { + [self.underlyingPushDeviceRegistrations save:deviceDetails + callback:callback]; +} + +@end diff --git a/Source/Ably.modulemap b/Source/Ably.modulemap index 329b9f2b5..a0d3c4419 100644 --- a/Source/Ably.modulemap +++ b/Source/Ably.modulemap @@ -118,5 +118,7 @@ framework module Ably { header "ARTChannel.h" header "ARTWrapperSDKProxyPush+Private.h" header "ARTWrapperSDKProxyPushAdmin+Private.h" + header "ARTWrapperSDKProxyPushDeviceRegistrations+Private.h" + header "ARTWrapperSDKProxyPushChannelSubscriptions+Private.h" } } diff --git a/Source/PrivateHeaders/Ably/ARTWrapperSDKProxyPushChannelSubscriptions+Private.h b/Source/PrivateHeaders/Ably/ARTWrapperSDKProxyPushChannelSubscriptions+Private.h new file mode 100644 index 000000000..5663c5edf --- /dev/null +++ b/Source/PrivateHeaders/Ably/ARTWrapperSDKProxyPushChannelSubscriptions+Private.h @@ -0,0 +1,14 @@ +#import + +@class ARTWrapperSDKProxyOptions; + +NS_ASSUME_NONNULL_BEGIN + +@interface ARTWrapperSDKProxyPushChannelSubscriptions () + +- (instancetype)initWithPushChannelSubscriptions:(ARTPushChannelSubscriptions *)pushChannelSubscriptions + proxyOptions:(ARTWrapperSDKProxyOptions *)proxyOptions NS_DESIGNATED_INITIALIZER; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Source/PrivateHeaders/Ably/ARTWrapperSDKProxyPushDeviceRegistrations+Private.h b/Source/PrivateHeaders/Ably/ARTWrapperSDKProxyPushDeviceRegistrations+Private.h new file mode 100644 index 000000000..51a078db3 --- /dev/null +++ b/Source/PrivateHeaders/Ably/ARTWrapperSDKProxyPushDeviceRegistrations+Private.h @@ -0,0 +1,14 @@ +#import + +@class ARTWrapperSDKProxyOptions; + +NS_ASSUME_NONNULL_BEGIN + +@interface ARTWrapperSDKProxyPushDeviceRegistrations () + +- (instancetype)initWithPushDeviceRegistrations:(ARTPushDeviceRegistrations *)pushDeviceRegistrations + proxyOptions:(ARTWrapperSDKProxyOptions *)proxyOptions NS_DESIGNATED_INITIALIZER; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Source/include/Ably.modulemap b/Source/include/Ably.modulemap index 4432ce740..c0fa82034 100644 --- a/Source/include/Ably.modulemap +++ b/Source/include/Ably.modulemap @@ -116,5 +116,7 @@ framework module Ably { header "Ably/ARTChannel.h" header "Ably/ARTWrapperSDKProxyPush+Private.h" header "Ably/ARTWrapperSDKProxyPushAdmin+Private.h" + header "Ably/ARTWrapperSDKProxyPushDeviceRegistrations+Private.h" + header "Ably/ARTWrapperSDKProxyPushChannelSubscriptions+Private.h" } } diff --git a/Source/include/Ably/ARTWrapperSDKProxyPushAdmin.h b/Source/include/Ably/ARTWrapperSDKProxyPushAdmin.h index 1b30ddebf..d6ce28af9 100644 --- a/Source/include/Ably/ARTWrapperSDKProxyPushAdmin.h +++ b/Source/include/Ably/ARTWrapperSDKProxyPushAdmin.h @@ -1,8 +1,8 @@ #import #import -@class ARTPushDeviceRegistrations; -@class ARTPushChannelSubscriptions; +@class ARTWrapperSDKProxyPushDeviceRegistrations; +@class ARTWrapperSDKProxyPushChannelSubscriptions; NS_ASSUME_NONNULL_BEGIN @@ -16,8 +16,8 @@ NS_SWIFT_SENDABLE - (instancetype)init NS_UNAVAILABLE; -@property (nonatomic, readonly) ARTPushDeviceRegistrations *deviceRegistrations; -@property (nonatomic, readonly) ARTPushChannelSubscriptions *channelSubscriptions; +@property (nonatomic, readonly) ARTWrapperSDKProxyPushDeviceRegistrations *deviceRegistrations; +@property (nonatomic, readonly) ARTWrapperSDKProxyPushChannelSubscriptions *channelSubscriptions; @end diff --git a/Source/include/Ably/ARTWrapperSDKProxyPushChannelSubscriptions.h b/Source/include/Ably/ARTWrapperSDKProxyPushChannelSubscriptions.h new file mode 100644 index 000000000..729ee19d7 --- /dev/null +++ b/Source/include/Ably/ARTWrapperSDKProxyPushChannelSubscriptions.h @@ -0,0 +1,18 @@ +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * An object which wraps an instance of `ARTPushChannelSubscriptions` and provides a similar API. It allows Ably-authored wrapper SDKs to send analytics information so that Ably can track the usage of the wrapper SDK. + * + * - Important: This class should only be used by Ably-authored SDKs. + */ +NS_SWIFT_SENDABLE +@interface ARTWrapperSDKProxyPushChannelSubscriptions : NSObject + +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Source/include/Ably/ARTWrapperSDKProxyPushDeviceRegistrations.h b/Source/include/Ably/ARTWrapperSDKProxyPushDeviceRegistrations.h new file mode 100644 index 000000000..d511de1f3 --- /dev/null +++ b/Source/include/Ably/ARTWrapperSDKProxyPushDeviceRegistrations.h @@ -0,0 +1,18 @@ +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * An object which wraps an instance of `ARTPushDeviceRegistrations` and provides a similar API. It allows Ably-authored wrapper SDKs to send analytics information so that Ably can track the usage of the wrapper SDK. + * + * - Important: This class should only be used by Ably-authored SDKs. + */ +NS_SWIFT_SENDABLE +@interface ARTWrapperSDKProxyPushDeviceRegistrations : NSObject + +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Source/include/Ably/AblyInternal.h b/Source/include/Ably/AblyInternal.h index 5e5a1ac5e..156f05503 100644 --- a/Source/include/Ably/AblyInternal.h +++ b/Source/include/Ably/AblyInternal.h @@ -7,3 +7,5 @@ #import #import #import +#import +#import From 5366073a2ad329daa7ad4749e609d420319be5f3 Mon Sep 17 00:00:00 2001 From: Lawrence Forooghian Date: Thu, 13 Feb 2025 10:57:45 -0300 Subject: [PATCH 11/16] Insert wrapper SDK agents in channel subscriptions and device registrations requests As in b006650. --- Source/ARTPushChannelSubscriptions.m | 35 ++++++++++--------- Source/ARTPushDeviceRegistrations.m | 30 ++++++++-------- ...TWrapperSDKProxyPushChannelSubscriptions.m | 25 ++++++++----- ...RTWrapperSDKProxyPushDeviceRegistrations.m | 27 ++++++++------ .../ARTPushChannelSubscriptions+Private.h | 10 +++--- .../Ably/ARTPushDeviceRegistrations+Private.h | 10 +++--- Test/Tests/WrapperSDKProxyTests.swift | 30 ++++++++++++++++ 7 files changed, 106 insertions(+), 61 deletions(-) diff --git a/Source/ARTPushChannelSubscriptions.m b/Source/ARTPushChannelSubscriptions.m index a121135a8..05b3cd6e6 100644 --- a/Source/ARTPushChannelSubscriptions.m +++ b/Source/ARTPushChannelSubscriptions.m @@ -24,23 +24,23 @@ - (instancetype)initWithInternal:(ARTPushChannelSubscriptionsInternal *)internal } - (void)save:(ARTPushChannelSubscription *)channelSubscription callback:(ARTCallback)callback { - [_internal save:channelSubscription callback:callback]; + [_internal save:channelSubscription wrapperSDKAgents:nil callback:callback]; } - (void)listChannels:(ARTPaginatedTextCallback)callback { - [_internal listChannels:callback]; + [_internal listChannelsWithWrapperSDKAgents:nil completion:callback]; } - (void)list:(NSStringDictionary *)params callback:(ARTPaginatedPushChannelCallback)callback { - [_internal list:params callback:callback]; + [_internal list:params wrapperSDKAgents:nil callback:callback]; } - (void)remove:(ARTPushChannelSubscription *)subscription callback:(ARTCallback)callback { - [_internal remove:subscription callback:callback]; + [_internal remove:subscription wrapperSDKAgents:nil callback:callback]; } - (void)removeWhere:(NSStringDictionary *)params callback:(ARTCallback)callback { - [_internal removeWhere:params callback:callback]; + [_internal removeWhere:params wrapperSDKAgents:nil callback:callback]; } @end @@ -62,7 +62,7 @@ - (instancetype)initWithRest:(ARTRestInternal *)rest logger:(ARTInternalLog *)lo return self; } -- (void)save:(ARTPushChannelSubscription *)channelSubscription callback:(ARTCallback)callback { +- (void)save:(ARTPushChannelSubscription *)channelSubscription wrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents callback:(ARTCallback)callback { if (callback) { ARTCallback userCallback = callback; callback = ^(ARTErrorInfo *error) { @@ -90,7 +90,7 @@ - (void)save:(ARTPushChannelSubscription *)channelSubscription callback:(ARTCall [request setDeviceAuthentication:channelSubscription.deviceId localDevice:local]; ARTLogDebug(self->_logger, @"save channel subscription with request %@", request); - [self->_rest executeRequest:request withAuthOption:ARTAuthenticationOn wrapperSDKAgents:nil completion:^(NSHTTPURLResponse *response, NSData *data, NSError *error) { + [self->_rest executeRequest:request withAuthOption:ARTAuthenticationOn wrapperSDKAgents:wrapperSDKAgents completion:^(NSHTTPURLResponse *response, NSData *data, NSError *error) { if (response.statusCode == 200 /*Ok*/ || response.statusCode == 201 /*Created*/) { ARTLogDebug(self->_logger, @"channel subscription saved successfully"); callback(nil); @@ -108,7 +108,8 @@ - (void)save:(ARTPushChannelSubscription *)channelSubscription callback:(ARTCall }); } -- (void)listChannels:(ARTPaginatedTextCallback)callback { +- (void)listChannelsWithWrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents + completion:(ARTPaginatedTextCallback)callback { if (callback) { void (^userCallback)(ARTPaginatedResult *, ARTErrorInfo *error) = callback; callback = ^(ARTPaginatedResult *result, ARTErrorInfo *error) { @@ -126,11 +127,11 @@ - (void)listChannels:(ARTPaginatedTextCallback)callback { ARTPaginatedResultResponseProcessor responseProcessor = ^(NSHTTPURLResponse *response, NSData *data, NSError **error) { return [self->_rest.encoders[response.MIMEType] decode:data error:error]; }; - [ARTPaginatedResult executePaginated:self->_rest withRequest:request andResponseProcessor:responseProcessor wrapperSDKAgents:nil logger:self->_logger callback:callback]; + [ARTPaginatedResult executePaginated:self->_rest withRequest:request andResponseProcessor:responseProcessor wrapperSDKAgents:wrapperSDKAgents logger:self->_logger callback:callback]; }); } -- (void)list:(NSStringDictionary *)params callback:(ARTPaginatedPushChannelCallback)callback { +- (void)list:(NSStringDictionary *)params wrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents callback:(ARTPaginatedPushChannelCallback)callback { if (callback) { void (^userCallback)(ARTPaginatedResult *, ARTErrorInfo *error) = callback; callback = ^(ARTPaginatedResult *result, ARTErrorInfo *error) { @@ -149,11 +150,11 @@ - (void)list:(NSStringDictionary *)params callback:(ARTPaginatedPushChannelCallb ARTPaginatedResultResponseProcessor responseProcessor = ^(NSHTTPURLResponse *response, NSData *data, NSError **error) { return [self->_rest.encoders[response.MIMEType] decodePushChannelSubscriptions:data error:error]; }; - [ARTPaginatedResult executePaginated:self->_rest withRequest:request andResponseProcessor:responseProcessor wrapperSDKAgents:nil logger:self->_logger callback:callback]; + [ARTPaginatedResult executePaginated:self->_rest withRequest:request andResponseProcessor:responseProcessor wrapperSDKAgents:wrapperSDKAgents logger:self->_logger callback:callback]; }); } -- (void)remove:(ARTPushChannelSubscription *)subscription callback:(ARTCallback)callback { +- (void)remove:(ARTPushChannelSubscription *)subscription wrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents callback:(ARTCallback)callback { if (callback) { ARTCallback userCallback = callback; callback = ^(ARTErrorInfo *error) { @@ -175,11 +176,11 @@ - (void)remove:(ARTPushChannelSubscription *)subscription callback:(ARTCallback) } else { where[@"clientId"] = subscription.clientId; } - [self _removeWhere:where callback:callback]; + [self _removeWhere:where wrapperSDKAgents:wrapperSDKAgents callback:callback]; }); } -- (void)removeWhere:(NSStringDictionary *)params callback:(ARTCallback)callback { +- (void)removeWhere:(NSStringDictionary *)params wrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents callback:(ARTCallback)callback { if (callback) { ARTCallback userCallback = callback; callback = ^(ARTErrorInfo *error) { @@ -190,11 +191,11 @@ - (void)removeWhere:(NSStringDictionary *)params callback:(ARTCallback)callback } dispatch_async(_queue, ^{ - [self _removeWhere:params callback:callback]; + [self _removeWhere:params wrapperSDKAgents:wrapperSDKAgents callback:callback]; }); } -- (void)_removeWhere:(NSStringDictionary *)params callback:(ARTCallback)callback { +- (void)_removeWhere:(NSStringDictionary *)params wrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents callback:(ARTCallback)callback { NSURLComponents *components = [[NSURLComponents alloc] initWithURL:[NSURL URLWithString:@"/push/channelSubscriptions"] resolvingAgainstBaseURL:NO]; components.queryItems = [params art_asURLQueryItems]; if (_rest.options.pushFullWait) { @@ -207,7 +208,7 @@ - (void)_removeWhere:(NSStringDictionary *)params callback:(ARTCallback)callback #endif ARTLogDebug(_logger, @"remove channel subscription with request %@", request); - [_rest executeRequest:request withAuthOption:ARTAuthenticationOn wrapperSDKAgents:nil completion:^(NSHTTPURLResponse *response, NSData *data, NSError *error) { + [_rest executeRequest:request withAuthOption:ARTAuthenticationOn wrapperSDKAgents:wrapperSDKAgents completion:^(NSHTTPURLResponse *response, NSData *data, NSError *error) { if (response.statusCode == 200 /*Ok*/ || response.statusCode == 204 /*not returning any content*/) { ARTLogDebug(self->_logger, @"%@: channel subscription removed successfully", NSStringFromClass(self.class)); callback(nil); diff --git a/Source/ARTPushDeviceRegistrations.m b/Source/ARTPushDeviceRegistrations.m index 493783061..4b8f3747b 100644 --- a/Source/ARTPushDeviceRegistrations.m +++ b/Source/ARTPushDeviceRegistrations.m @@ -25,23 +25,23 @@ - (instancetype)initWithInternal:(ARTPushDeviceRegistrationsInternal *)internal } - (void)save:(ARTDeviceDetails *)deviceDetails callback:(ARTCallback)callback { - [_internal save:deviceDetails callback:callback]; + [_internal save:deviceDetails wrapperSDKAgents:nil callback:callback]; } - (void)get:(ARTDeviceId *)deviceId callback:(void (^)(ARTDeviceDetails *_Nullable, ARTErrorInfo *_Nullable))callback { - [_internal get:deviceId callback:callback]; + [_internal get:deviceId wrapperSDKAgents:nil callback:callback]; } - (void)list:(NSStringDictionary *)params callback:(ARTPaginatedDeviceDetailsCallback)callback { - [_internal list:params callback:callback]; + [_internal list:params wrapperSDKAgents:nil callback:callback]; } - (void)remove:(NSString *)deviceId callback:(ARTCallback)callback { - [_internal remove:deviceId callback:callback]; + [_internal remove:deviceId wrapperSDKAgents:nil callback:callback]; } - (void)removeWhere:(NSStringDictionary *)params callback:(ARTCallback)callback { - [_internal removeWhere:params callback:callback]; + [_internal removeWhere:params wrapperSDKAgents:nil callback:callback]; } @end @@ -63,7 +63,7 @@ - (instancetype)initWithRest:(ARTRestInternal *)rest logger:(ARTInternalLog *)lo return self; } -- (void)save:(ARTDeviceDetails *)deviceDetails callback:(ARTCallback)callback { +- (void)save:(ARTDeviceDetails *)deviceDetails wrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents callback:(ARTCallback)callback { if (callback) { ARTCallback userCallback = callback; callback = ^(ARTErrorInfo *error) { @@ -91,7 +91,7 @@ - (void)save:(ARTDeviceDetails *)deviceDetails callback:(ARTCallback)callback { [request setDeviceAuthentication:deviceDetails.id localDevice:local logger:self->_logger]; ARTLogDebug(self->_logger, @"save device with request %@", request); - [self->_rest executeRequest:request withAuthOption:ARTAuthenticationOn wrapperSDKAgents:nil completion:^(NSHTTPURLResponse *response, NSData *data, NSError *error) { + [self->_rest executeRequest:request withAuthOption:ARTAuthenticationOn wrapperSDKAgents:wrapperSDKAgents completion:^(NSHTTPURLResponse *response, NSData *data, NSError *error) { if (response.statusCode == 200 /*OK*/) { NSError *decodeError = nil; ARTDeviceDetails *deviceDetails = [[self->_rest defaultEncoder] decodeDeviceDetails:data error:&decodeError]; @@ -117,7 +117,7 @@ - (void)save:(ARTDeviceDetails *)deviceDetails callback:(ARTCallback)callback { }); } -- (void)get:(ARTDeviceId *)deviceId callback:(void (^)(ARTDeviceDetails *, ARTErrorInfo *))callback { +- (void)get:(ARTDeviceId *)deviceId wrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents callback:(void (^)(ARTDeviceDetails *, ARTErrorInfo *))callback { if (callback) { void (^userCallback)(ARTDeviceDetails *, ARTErrorInfo *error) = callback; callback = ^(ARTDeviceDetails *device, ARTErrorInfo *error) { @@ -139,7 +139,7 @@ - (void)get:(ARTDeviceId *)deviceId callback:(void (^)(ARTDeviceDetails *, ARTEr [request setDeviceAuthentication:deviceId localDevice:local logger:self->_logger]; ARTLogDebug(self->_logger, @"get device with request %@", request); - [self->_rest executeRequest:request withAuthOption:ARTAuthenticationOn wrapperSDKAgents:nil completion:^(NSHTTPURLResponse *response, NSData *data, NSError *error) { + [self->_rest executeRequest:request withAuthOption:ARTAuthenticationOn wrapperSDKAgents:wrapperSDKAgents completion:^(NSHTTPURLResponse *response, NSData *data, NSError *error) { if (response.statusCode == 200 /*OK*/) { NSError *decodeError = nil; ARTDeviceDetails *device = [self->_rest.encoders[response.MIMEType] decodeDeviceDetails:data error:&decodeError]; @@ -169,7 +169,7 @@ - (void)get:(ARTDeviceId *)deviceId callback:(void (^)(ARTDeviceDetails *, ARTEr }); } -- (void)list:(NSStringDictionary *)params callback:(ARTPaginatedDeviceDetailsCallback)callback { +- (void)list:(NSStringDictionary *)params wrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents callback:(ARTPaginatedDeviceDetailsCallback)callback { if (callback) { void (^userCallback)(ARTPaginatedResult *, ARTErrorInfo *error) = callback; callback = ^(ARTPaginatedResult *result, ARTErrorInfo *error) { @@ -188,11 +188,11 @@ - (void)list:(NSStringDictionary *)params callback:(ARTPaginatedDeviceDetailsCal ARTPaginatedResultResponseProcessor responseProcessor = ^(NSHTTPURLResponse *response, NSData *data, NSError **error) { return [self->_rest.encoders[response.MIMEType] decodeDevicesDetails:data error:error]; }; - [ARTPaginatedResult executePaginated:self->_rest withRequest:request andResponseProcessor:responseProcessor wrapperSDKAgents:nil logger:self->_logger callback:callback]; + [ARTPaginatedResult executePaginated:self->_rest withRequest:request andResponseProcessor:responseProcessor wrapperSDKAgents:wrapperSDKAgents logger:self->_logger callback:callback]; }); } -- (void)remove:(NSString *)deviceId callback:(ARTCallback)callback { +- (void)remove:(NSString *)deviceId wrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents callback:(ARTCallback)callback { if (callback) { ARTCallback userCallback = callback; callback = ^(ARTErrorInfo *error) { @@ -212,7 +212,7 @@ - (void)remove:(NSString *)deviceId callback:(ARTCallback)callback { [request setValue:[[self->_rest defaultEncoder] mimeType] forHTTPHeaderField:@"Content-Type"]; ARTLogDebug(self->_logger, @"remove device with request %@", request); - [self->_rest executeRequest:request withAuthOption:ARTAuthenticationOn wrapperSDKAgents:nil completion:^(NSHTTPURLResponse *response, NSData *data, NSError *error) { + [self->_rest executeRequest:request withAuthOption:ARTAuthenticationOn wrapperSDKAgents:wrapperSDKAgents completion:^(NSHTTPURLResponse *response, NSData *data, NSError *error) { if (response.statusCode == 200 /*Ok*/ || response.statusCode == 204 /*not returning any content*/) { ARTLogDebug(self->_logger, @"%@: save device successfully", NSStringFromClass(self.class)); callback(nil); @@ -230,7 +230,7 @@ - (void)remove:(NSString *)deviceId callback:(ARTCallback)callback { }); } -- (void)removeWhere:(NSStringDictionary *)params callback:(ARTCallback)callback { +- (void)removeWhere:(NSStringDictionary *)params wrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents callback:(ARTCallback)callback { if (callback) { ARTCallback userCallback = callback; callback = ^(ARTErrorInfo *error) { @@ -257,7 +257,7 @@ - (void)removeWhere:(NSStringDictionary *)params callback:(ARTCallback)callback [request setDeviceAuthentication:[params objectForKey:@"deviceId"] localDevice:local]; ARTLogDebug(self->_logger, @"remove devices with request %@", request); - [self->_rest executeRequest:request withAuthOption:ARTAuthenticationOn wrapperSDKAgents:nil completion:^(NSHTTPURLResponse *response, NSData *data, NSError *error) { + [self->_rest executeRequest:request withAuthOption:ARTAuthenticationOn wrapperSDKAgents:wrapperSDKAgents completion:^(NSHTTPURLResponse *response, NSData *data, NSError *error) { if (response.statusCode == 200 /*Ok*/ || response.statusCode == 204 /*not returning any content*/) { ARTLogDebug(self->_logger, @"%@: remove devices successfully", NSStringFromClass(self.class)); callback(nil); diff --git a/Source/ARTWrapperSDKProxyPushChannelSubscriptions.m b/Source/ARTWrapperSDKProxyPushChannelSubscriptions.m index 06ed799bc..d14865b0f 100644 --- a/Source/ARTWrapperSDKProxyPushChannelSubscriptions.m +++ b/Source/ARTWrapperSDKProxyPushChannelSubscriptions.m @@ -1,4 +1,6 @@ #import "ARTWrapperSDKProxyPushChannelSubscriptions+Private.h" +#import "ARTWrapperSDKProxyOptions.h" +#import "ARTPushChannelSubscriptions+Private.h" NS_ASSUME_NONNULL_BEGIN @@ -23,27 +25,32 @@ - (instancetype)initWithPushChannelSubscriptions:(ARTPushChannelSubscriptions *) } - (void)list:(nonnull NSStringDictionary *)params callback:(nonnull ARTPaginatedPushChannelCallback)callback { - [self.underlyingPushChannelSubscriptions list:params - callback:callback]; + [self.underlyingPushChannelSubscriptions.internal list:params + wrapperSDKAgents:self.proxyOptions.agents + callback:callback]; } - (void)listChannels:(nonnull ARTPaginatedTextCallback)callback { - [self.underlyingPushChannelSubscriptions listChannels:callback]; + [self.underlyingPushChannelSubscriptions.internal listChannelsWithWrapperSDKAgents:self.proxyOptions.agents + completion:callback]; } - (void)remove:(nonnull ARTPushChannelSubscription *)subscription callback:(nonnull ARTCallback)callback { - [self.underlyingPushChannelSubscriptions remove:subscription - callback:callback]; + [self.underlyingPushChannelSubscriptions.internal remove:subscription + wrapperSDKAgents:self.proxyOptions.agents + callback:callback]; } - (void)removeWhere:(nonnull NSStringDictionary *)params callback:(nonnull ARTCallback)callback { - [self.underlyingPushChannelSubscriptions removeWhere:params - callback:callback]; + [self.underlyingPushChannelSubscriptions.internal removeWhere:params + wrapperSDKAgents:self.proxyOptions.agents + callback:callback]; } - (void)save:(nonnull ARTPushChannelSubscription *)channelSubscription callback:(nonnull ARTCallback)callback { - [self.underlyingPushChannelSubscriptions save:channelSubscription - callback:callback]; + [self.underlyingPushChannelSubscriptions.internal save:channelSubscription + wrapperSDKAgents:self.proxyOptions.agents + callback:callback]; } @end diff --git a/Source/ARTWrapperSDKProxyPushDeviceRegistrations.m b/Source/ARTWrapperSDKProxyPushDeviceRegistrations.m index cae14e242..9a2b7c13b 100644 --- a/Source/ARTWrapperSDKProxyPushDeviceRegistrations.m +++ b/Source/ARTWrapperSDKProxyPushDeviceRegistrations.m @@ -1,4 +1,6 @@ #import "ARTWrapperSDKProxyPushDeviceRegistrations+Private.h" +#import "ARTWrapperSDKProxyOptions.h" +#import "ARTPushDeviceRegistrations+Private.h" NS_ASSUME_NONNULL_BEGIN @@ -23,28 +25,33 @@ - (instancetype)initWithPushDeviceRegistrations:(ARTPushDeviceRegistrations *)pu } - (void)get:(nonnull ARTDeviceId *)deviceId callback:(nonnull void (^)(ARTDeviceDetails * _Nullable, ARTErrorInfo * _Nullable))callback { - [self.underlyingPushDeviceRegistrations get:deviceId - callback:callback]; + [self.underlyingPushDeviceRegistrations.internal get:deviceId + wrapperSDKAgents:self.proxyOptions.agents + callback:callback]; } - (void)list:(nonnull NSStringDictionary *)params callback:(nonnull ARTPaginatedDeviceDetailsCallback)callback { - [self.underlyingPushDeviceRegistrations list:params - callback:callback]; + [self.underlyingPushDeviceRegistrations.internal list:params + wrapperSDKAgents:self.proxyOptions.agents + callback:callback]; } - (void)remove:(nonnull NSString *)deviceId callback:(nonnull ARTCallback)callback { - [self.underlyingPushDeviceRegistrations remove:deviceId - callback:callback]; + [self.underlyingPushDeviceRegistrations.internal remove:deviceId + wrapperSDKAgents:self.proxyOptions.agents + callback:callback]; } - (void)removeWhere:(nonnull NSStringDictionary *)params callback:(nonnull ARTCallback)callback { - [self.underlyingPushDeviceRegistrations removeWhere:params - callback:callback]; + [self.underlyingPushDeviceRegistrations.internal removeWhere:params + wrapperSDKAgents:self.proxyOptions.agents + callback:callback]; } - (void)save:(nonnull ARTDeviceDetails *)deviceDetails callback:(nonnull ARTCallback)callback { - [self.underlyingPushDeviceRegistrations save:deviceDetails - callback:callback]; + [self.underlyingPushDeviceRegistrations.internal save:deviceDetails + wrapperSDKAgents:self.proxyOptions.agents + callback:callback]; } @end diff --git a/Source/PrivateHeaders/Ably/ARTPushChannelSubscriptions+Private.h b/Source/PrivateHeaders/Ably/ARTPushChannelSubscriptions+Private.h index b4225d68d..2e3905045 100644 --- a/Source/PrivateHeaders/Ably/ARTPushChannelSubscriptions+Private.h +++ b/Source/PrivateHeaders/Ably/ARTPushChannelSubscriptions+Private.h @@ -10,15 +10,15 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)initWithRest:(ARTRestInternal *)rest logger:(ARTInternalLog *)logger; -- (void)save:(ARTPushChannelSubscription *)channelSubscription callback:(ARTCallback)callback; +- (void)save:(ARTPushChannelSubscription *)channelSubscription wrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents callback:(ARTCallback)callback; -- (void)listChannels:(ARTPaginatedTextCallback)callback; +- (void)listChannelsWithWrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents completion:(ARTPaginatedTextCallback)callback; -- (void)list:(NSStringDictionary *)params callback:(ARTPaginatedPushChannelCallback)callback; +- (void)list:(NSStringDictionary *)params wrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents callback:(ARTPaginatedPushChannelCallback)callback; -- (void)remove:(ARTPushChannelSubscription *)subscription callback:(ARTCallback)callback; +- (void)remove:(ARTPushChannelSubscription *)subscription wrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents callback:(ARTCallback)callback; -- (void)removeWhere:(NSStringDictionary *)params callback:(ARTCallback)callback; +- (void)removeWhere:(NSStringDictionary *)params wrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents callback:(ARTCallback)callback; @end diff --git a/Source/PrivateHeaders/Ably/ARTPushDeviceRegistrations+Private.h b/Source/PrivateHeaders/Ably/ARTPushDeviceRegistrations+Private.h index bb62b8daf..eec91e1d3 100644 --- a/Source/PrivateHeaders/Ably/ARTPushDeviceRegistrations+Private.h +++ b/Source/PrivateHeaders/Ably/ARTPushDeviceRegistrations+Private.h @@ -10,15 +10,15 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)initWithRest:(ARTRestInternal *)rest logger:(ARTInternalLog *)logger; -- (void)save:(ARTDeviceDetails *)deviceDetails callback:(ARTCallback)callback; +- (void)save:(ARTDeviceDetails *)deviceDetails wrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents callback:(ARTCallback)callback; -- (void)get:(ARTDeviceId *)deviceId callback:(void (^)(ARTDeviceDetails *_Nullable, ARTErrorInfo *_Nullable))callback; +- (void)get:(ARTDeviceId *)deviceId wrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents callback:(void (^)(ARTDeviceDetails *_Nullable, ARTErrorInfo *_Nullable))callback; -- (void)list:(NSStringDictionary *)params callback:(ARTPaginatedDeviceDetailsCallback)callback; +- (void)list:(NSStringDictionary *)params wrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents callback:(ARTPaginatedDeviceDetailsCallback)callback; -- (void)remove:(NSString *)deviceId callback:(ARTCallback)callback; +- (void)remove:(NSString *)deviceId wrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents callback:(ARTCallback)callback; -- (void)removeWhere:(NSStringDictionary *)params callback:(ARTCallback)callback; +- (void)removeWhere:(NSStringDictionary *)params wrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents callback:(ARTCallback)callback; @end diff --git a/Test/Tests/WrapperSDKProxyTests.swift b/Test/Tests/WrapperSDKProxyTests.swift index 3862a36bb..23e89f0c8 100644 --- a/Test/Tests/WrapperSDKProxyTests.swift +++ b/Test/Tests/WrapperSDKProxyTests.swift @@ -443,6 +443,36 @@ class WrapperSDKProxyTests: XCTestCase { } } + func test_pushAdmin_channelSubscriptions_addsWrapperSDKAgentToRequests() throws { + let test = Test() + + // We just do a smoke test of one of the methods offered by this class + + try parameterizedTest_addsWrapperSDKAgentToRequests(test: test) { proxyClient in + waitUntil(timeout: testTimeout) { done in + proxyClient.push.admin.channelSubscriptions.listChannels { _, error in + XCTAssertNil(error) + done() + } + } + } + } + + func test_pushAdmin_deviceRegistrations_addsWrapperSDKAgentToRequests() throws { + let test = Test() + + // We just do a smoke test of one of the methods offered by this class + + try parameterizedTest_addsWrapperSDKAgentToRequests(test: test) { proxyClient in + waitUntil(timeout: testTimeout) { done in + proxyClient.push.admin.deviceRegistrations.list([:]) { _, error in + XCTAssertNil(error) + done() + } + } + } + } + // MARK: - `agent` channel param private func parameterizedTest_checkAttachProtocolMessage( From 5d9a04fa432d6c8c01da76cfa7a6bb1a03e06b85 Mon Sep 17 00:00:00 2001 From: Lawrence Forooghian Date: Thu, 13 Feb 2025 14:42:22 -0300 Subject: [PATCH 12/16] Create wrapper SDK proxy push channel As in 4daf4ba. --- Ably.xcodeproj/project.pbxproj | 24 ++++++++ Source/ARTWrapperSDKProxyPushChannel.m | 61 +++++++++++++++++++ Source/ARTWrapperSDKProxyRealtimeChannel.m | 11 ++-- Source/Ably.modulemap | 1 + .../ARTWrapperSDKProxyPushChannel+Private.h | 14 +++++ Source/include/Ably.modulemap | 1 + .../Ably/ARTWrapperSDKProxyPushChannel.h | 18 ++++++ .../Ably/ARTWrapperSDKProxyRealtimeChannel.h | 3 +- Source/include/Ably/AblyInternal.h | 1 + 9 files changed, 127 insertions(+), 7 deletions(-) create mode 100644 Source/ARTWrapperSDKProxyPushChannel.m create mode 100644 Source/PrivateHeaders/Ably/ARTWrapperSDKProxyPushChannel+Private.h create mode 100644 Source/include/Ably/ARTWrapperSDKProxyPushChannel.h diff --git a/Ably.xcodeproj/project.pbxproj b/Ably.xcodeproj/project.pbxproj index d246a911e..68f0da69c 100644 --- a/Ably.xcodeproj/project.pbxproj +++ b/Ably.xcodeproj/project.pbxproj @@ -244,6 +244,15 @@ 215924B72D636B89004A235C /* ARTWrapperSDKProxyPushDeviceRegistrations.m in Sources */ = {isa = PBXBuildFile; fileRef = 215924B32D636B89004A235C /* ARTWrapperSDKProxyPushDeviceRegistrations.m */; }; 215924B82D636B89004A235C /* ARTWrapperSDKProxyPushChannelSubscriptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 215924B22D636B89004A235C /* ARTWrapperSDKProxyPushChannelSubscriptions.m */; }; 215924B92D636B89004A235C /* ARTWrapperSDKProxyPushDeviceRegistrations.m in Sources */ = {isa = PBXBuildFile; fileRef = 215924B32D636B89004A235C /* ARTWrapperSDKProxyPushDeviceRegistrations.m */; }; + 215924C32D636D2F004A235C /* ARTWrapperSDKProxyPushChannel.m in Sources */ = {isa = PBXBuildFile; fileRef = 215924C22D636D2F004A235C /* ARTWrapperSDKProxyPushChannel.m */; }; + 215924C42D636D2F004A235C /* ARTWrapperSDKProxyPushChannel.m in Sources */ = {isa = PBXBuildFile; fileRef = 215924C22D636D2F004A235C /* ARTWrapperSDKProxyPushChannel.m */; }; + 215924C52D636D2F004A235C /* ARTWrapperSDKProxyPushChannel.m in Sources */ = {isa = PBXBuildFile; fileRef = 215924C22D636D2F004A235C /* ARTWrapperSDKProxyPushChannel.m */; }; + 215924C72D636D43004A235C /* ARTWrapperSDKProxyPushChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 215924C62D636D43004A235C /* ARTWrapperSDKProxyPushChannel.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 215924C82D636D43004A235C /* ARTWrapperSDKProxyPushChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 215924C62D636D43004A235C /* ARTWrapperSDKProxyPushChannel.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 215924C92D636D43004A235C /* ARTWrapperSDKProxyPushChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 215924C62D636D43004A235C /* ARTWrapperSDKProxyPushChannel.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 215924CB2D636D50004A235C /* ARTWrapperSDKProxyPushChannel+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 215924CA2D636D50004A235C /* ARTWrapperSDKProxyPushChannel+Private.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 215924CC2D636D50004A235C /* ARTWrapperSDKProxyPushChannel+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 215924CA2D636D50004A235C /* ARTWrapperSDKProxyPushChannel+Private.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 215924CD2D636D50004A235C /* ARTWrapperSDKProxyPushChannel+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 215924CA2D636D50004A235C /* ARTWrapperSDKProxyPushChannel+Private.h */; settings = {ATTRIBUTES = (Private, ); }; }; 215F75F82922B1DB009E0E76 /* ARTClientInformation.h in Headers */ = {isa = PBXBuildFile; fileRef = 215F75F62922B1DB009E0E76 /* ARTClientInformation.h */; settings = {ATTRIBUTES = (Public, ); }; }; 215F75F92922B1DB009E0E76 /* ARTClientInformation.h in Headers */ = {isa = PBXBuildFile; fileRef = 215F75F62922B1DB009E0E76 /* ARTClientInformation.h */; settings = {ATTRIBUTES = (Public, ); }; }; 215F75FA2922B1DB009E0E76 /* ARTClientInformation.h in Headers */ = {isa = PBXBuildFile; fileRef = 215F75F62922B1DB009E0E76 /* ARTClientInformation.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -1289,6 +1298,9 @@ 215924AB2D636B6B004A235C /* ARTWrapperSDKProxyPushDeviceRegistrations+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "ARTWrapperSDKProxyPushDeviceRegistrations+Private.h"; path = "PrivateHeaders/Ably/ARTWrapperSDKProxyPushDeviceRegistrations+Private.h"; sourceTree = ""; }; 215924B22D636B89004A235C /* ARTWrapperSDKProxyPushChannelSubscriptions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ARTWrapperSDKProxyPushChannelSubscriptions.m; sourceTree = ""; }; 215924B32D636B89004A235C /* ARTWrapperSDKProxyPushDeviceRegistrations.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ARTWrapperSDKProxyPushDeviceRegistrations.m; sourceTree = ""; }; + 215924C22D636D2F004A235C /* ARTWrapperSDKProxyPushChannel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ARTWrapperSDKProxyPushChannel.m; sourceTree = ""; }; + 215924C62D636D43004A235C /* ARTWrapperSDKProxyPushChannel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ARTWrapperSDKProxyPushChannel.h; path = include/Ably/ARTWrapperSDKProxyPushChannel.h; sourceTree = ""; }; + 215924CA2D636D50004A235C /* ARTWrapperSDKProxyPushChannel+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "ARTWrapperSDKProxyPushChannel+Private.h"; path = "PrivateHeaders/Ably/ARTWrapperSDKProxyPushChannel+Private.h"; sourceTree = ""; }; 215F75F62922B1DB009E0E76 /* ARTClientInformation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ARTClientInformation.h; path = include/Ably/ARTClientInformation.h; sourceTree = ""; }; 215F75F72922B1DB009E0E76 /* ARTClientInformation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ARTClientInformation.m; sourceTree = ""; }; 215F75FE2922B30F009E0E76 /* ClientInformationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClientInformationTests.swift; sourceTree = ""; }; @@ -1727,6 +1739,9 @@ 215924A22D636B5C004A235C /* ARTWrapperSDKProxyPushChannelSubscriptions.h */, 215924AA2D636B6B004A235C /* ARTWrapperSDKProxyPushChannelSubscriptions+Private.h */, 215924B22D636B89004A235C /* ARTWrapperSDKProxyPushChannelSubscriptions.m */, + 215924C62D636D43004A235C /* ARTWrapperSDKProxyPushChannel.h */, + 215924CA2D636D50004A235C /* ARTWrapperSDKProxyPushChannel+Private.h */, + 215924C22D636D2F004A235C /* ARTWrapperSDKProxyPushChannel.m */, ); name = "Wrapper SDK Proxy"; sourceTree = ""; @@ -2392,6 +2407,7 @@ 961343D81A42E0B7006DC822 /* ARTClientOptions.h in Headers */, 2105ED1A29E722DD00DE6D67 /* ARTInternalLogCore+Testing.h in Headers */, D7534C321D79E5C20054C182 /* Ably.h in Headers */, + 215924C92D636D43004A235C /* ARTWrapperSDKProxyPushChannel.h in Headers */, D777EEE0206285CF002EBA03 /* ARTDeviceIdentityTokenDetails.h in Headers */, 2124B79F29DB14D000AD8361 /* ARTLogAdapter.h in Headers */, 215F76032922C76C009E0E76 /* ARTClientInformation+Private.h in Headers */, @@ -2544,6 +2560,7 @@ D3AD0EBD215E2FB000312105 /* ARTNSString+ARTUtil.h in Headers */, 215924B02D636B6B004A235C /* ARTWrapperSDKProxyPushDeviceRegistrations+Private.h in Headers */, 215924B12D636B6B004A235C /* ARTWrapperSDKProxyPushChannelSubscriptions+Private.h in Headers */, + 215924CB2D636D50004A235C /* ARTWrapperSDKProxyPushChannel+Private.h in Headers */, EB2D85011CD769C800F23CDA /* ARTOSReachability.h in Headers */, 21E1C0E52A0DC47400A5DB65 /* ARTWebSocketFactory.h in Headers */, EB1B541522FB1CE1006A59AC /* ARTPushDeviceRegistrations+Private.h in Headers */, @@ -2680,6 +2697,7 @@ 2132C21B29D230CF000C4355 /* ARTErrorChecker.h in Headers */, D710D51B21949C42008F54AD /* ARTDeviceIdentityTokenDetails.h in Headers */, D76F153D23DB012100B5133C /* ARTRealtimeChannelOptions.h in Headers */, + 215924CD2D636D50004A235C /* ARTWrapperSDKProxyPushChannel+Private.h in Headers */, D5D83C0826AAED1A00AADC8E /* ARTStringifiable+Private.h in Headers */, D710D48021949A42008F54AD /* ARTDefault.h in Headers */, 2124B7A429DB153500AD8361 /* ARTDeviceIdentityTokenDetails+Private.h in Headers */, @@ -2741,6 +2759,7 @@ 215924AF2D636B6B004A235C /* ARTWrapperSDKProxyPushChannelSubscriptions+Private.h in Headers */, 2114D4302D4BCAE20032839A /* ARTRealtime+WrapperSDKProxy.h in Headers */, D710D4BF21949B6C008F54AD /* ARTNSMutableRequest+ARTRest.h in Headers */, + 215924C82D636D43004A235C /* ARTWrapperSDKProxyPushChannel.h in Headers */, 2147F02E29E583AD0071CB94 /* ARTInternalLogCore.h in Headers */, D710D5BE21949D4F008F54AD /* ARTBaseMessage+Private.h in Headers */, D5BB20FE26A7F50000AA5F3E /* ARTSRPinningSecurityPolicy.h in Headers */, @@ -2869,6 +2888,7 @@ 2132C21C29D230D0000C4355 /* ARTErrorChecker.h in Headers */, D5BB210F26AA98A900AA5F3E /* ARTStringifiable.h in Headers */, D5C0CB3F268317B500C06521 /* NSURLQueryItem+Stringifiable.h in Headers */, + 215924CC2D636D50004A235C /* ARTWrapperSDKProxyPushChannel+Private.h in Headers */, D710D52D21949C44008F54AD /* ARTDeviceIdentityTokenDetails.h in Headers */, D76F153E23DB012100B5133C /* ARTRealtimeChannelOptions.h in Headers */, D710D48221949A43008F54AD /* ARTDefault.h in Headers */, @@ -2930,6 +2950,7 @@ 215924AD2D636B6B004A235C /* ARTWrapperSDKProxyPushChannelSubscriptions+Private.h in Headers */, 2114D42F2D4BCAE20032839A /* ARTRealtime+WrapperSDKProxy.h in Headers */, D710D4C121949B6D008F54AD /* ARTNSMutableRequest+ARTRest.h in Headers */, + 215924C72D636D43004A235C /* ARTWrapperSDKProxyPushChannel.h in Headers */, 2147F02F29E583AD0071CB94 /* ARTInternalLogCore.h in Headers */, D710D5CE21949D50008F54AD /* ARTBaseMessage+Private.h in Headers */, D5BB20FF26A7F50800AA5F3E /* ARTSRPinningSecurityPolicy.h in Headers */, @@ -3433,6 +3454,7 @@ 96A507A61A377DE90077CDF8 /* ARTNSDictionary+ARTDictionaryUtil.m in Sources */, 217D182D254222F500DFF07E /* ARTSRSIMDHelpers.m in Sources */, D5BB210D26AA98A500AA5F3E /* ARTStringifiable.m in Sources */, + 215924C52D636D2F004A235C /* ARTWrapperSDKProxyPushChannel.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3685,6 +3707,7 @@ D710D53821949C54008F54AD /* ARTLocalDeviceStorage.m in Sources */, D5BB210C26AA98A500AA5F3E /* ARTStringifiable.m in Sources */, 217D1844254222F700DFF07E /* ARTSRSIMDHelpers.m in Sources */, + 215924C32D636D2F004A235C /* ARTWrapperSDKProxyPushChannel.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3817,6 +3840,7 @@ D710D60221949D79008F54AD /* ARTPresence.m in Sources */, D710D54A21949C55008F54AD /* ARTLocalDeviceStorage.m in Sources */, 217D185B254222F900DFF07E /* ARTSRSIMDHelpers.m in Sources */, + 215924C42D636D2F004A235C /* ARTWrapperSDKProxyPushChannel.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Source/ARTWrapperSDKProxyPushChannel.m b/Source/ARTWrapperSDKProxyPushChannel.m new file mode 100644 index 000000000..216a58308 --- /dev/null +++ b/Source/ARTWrapperSDKProxyPushChannel.m @@ -0,0 +1,61 @@ +#import "ARTWrapperSDKProxyPushChannel+Private.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface ARTWrapperSDKProxyPushChannel () + +@property (nonatomic, readonly) ARTPushChannel *underlyingPushChannel; +@property (nonatomic, readonly) ARTWrapperSDKProxyOptions *proxyOptions; + +@end + +NS_ASSUME_NONNULL_END + +@implementation ARTWrapperSDKProxyPushChannel + +- (instancetype)initWithPushChannel:(ARTPushChannel *)pushChannel proxyOptions:(ARTWrapperSDKProxyOptions *)proxyOptions { + if (self = [super init]) { + _underlyingPushChannel = pushChannel; + _proxyOptions = proxyOptions; + } + + return self; +} + +- (BOOL)listSubscriptions:(nonnull NSStringDictionary *)params callback:(nonnull ARTPaginatedPushChannelCallback)callback error:(NSError * _Nullable __autoreleasing * _Nullable)errorPtr { + return [self.underlyingPushChannel listSubscriptions:params callback:callback error:errorPtr]; +} + +- (void)subscribeClient { + [self.underlyingPushChannel subscribeClient]; +} + +- (void)subscribeClient:(nullable ARTCallback)callback { + [self.underlyingPushChannel subscribeClient:callback]; +} + +- (void)subscribeDevice { + [self.underlyingPushChannel subscribeDevice]; +} + +- (void)subscribeDevice:(nullable ARTCallback)callback { + [self.underlyingPushChannel subscribeDevice:callback]; +} + +- (void)unsubscribeClient { + [self.underlyingPushChannel unsubscribeClient]; +} + +- (void)unsubscribeClient:(nullable ARTCallback)callback { + [self.underlyingPushChannel unsubscribeClient:callback]; +} + +- (void)unsubscribeDevice { + [self.underlyingPushChannel unsubscribeDevice]; +} + +- (void)unsubscribeDevice:(nullable ARTCallback)callback { + [self.underlyingPushChannel unsubscribeDevice:callback]; +} + +@end diff --git a/Source/ARTWrapperSDKProxyRealtimeChannel.m b/Source/ARTWrapperSDKProxyRealtimeChannel.m index 01a202364..e33f2cae0 100644 --- a/Source/ARTWrapperSDKProxyRealtimeChannel.m +++ b/Source/ARTWrapperSDKProxyRealtimeChannel.m @@ -1,6 +1,7 @@ #import "ARTWrapperSDKProxyRealtimeChannel+Private.h" #import "ARTRealtimeChannel+Private.h" #import "ARTWrapperSDKProxyOptions.h" +#import "ARTWrapperSDKProxyPushChannel+Private.h" NS_ASSUME_NONNULL_BEGIN @@ -19,6 +20,10 @@ - (instancetype)initWithChannel:(ARTRealtimeChannel *)channel proxyOptions:(ARTW if (self = [super init]) { _underlyingChannel = channel; _proxyOptions = proxyOptions; +#if TARGET_OS_IOS + _push = [[ARTWrapperSDKProxyPushChannel alloc] initWithPushChannel:channel.push + proxyOptions:proxyOptions]; +#endif } return self; @@ -49,12 +54,6 @@ - (ARTRealtimeChannelState)state { } -#if TARGET_OS_IOS -- (ARTPushChannel *)push { - return self.underlyingChannel.push; -} -#endif - - (void)history:(nonnull ARTPaginatedMessagesCallback)callback { [self.underlyingChannel.internal historyWithWrapperSDKAgents:self.proxyOptions.agents completion:callback]; diff --git a/Source/Ably.modulemap b/Source/Ably.modulemap index a0d3c4419..32c6eb4ad 100644 --- a/Source/Ably.modulemap +++ b/Source/Ably.modulemap @@ -120,5 +120,6 @@ framework module Ably { header "ARTWrapperSDKProxyPushAdmin+Private.h" header "ARTWrapperSDKProxyPushDeviceRegistrations+Private.h" header "ARTWrapperSDKProxyPushChannelSubscriptions+Private.h" + header "ARTWrapperSDKProxyPushChannel+Private.h" } } diff --git a/Source/PrivateHeaders/Ably/ARTWrapperSDKProxyPushChannel+Private.h b/Source/PrivateHeaders/Ably/ARTWrapperSDKProxyPushChannel+Private.h new file mode 100644 index 000000000..3727e1504 --- /dev/null +++ b/Source/PrivateHeaders/Ably/ARTWrapperSDKProxyPushChannel+Private.h @@ -0,0 +1,14 @@ +#import + +@class ARTWrapperSDKProxyOptions; + +NS_ASSUME_NONNULL_BEGIN + +@interface ARTWrapperSDKProxyPushChannel () + +- (instancetype)initWithPushChannel:(ARTPushChannel *)pushChannel + proxyOptions:(ARTWrapperSDKProxyOptions *)proxyOptions NS_DESIGNATED_INITIALIZER; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Source/include/Ably.modulemap b/Source/include/Ably.modulemap index c0fa82034..4019339d1 100644 --- a/Source/include/Ably.modulemap +++ b/Source/include/Ably.modulemap @@ -118,5 +118,6 @@ framework module Ably { header "Ably/ARTWrapperSDKProxyPushAdmin+Private.h" header "Ably/ARTWrapperSDKProxyPushDeviceRegistrations+Private.h" header "Ably/ARTWrapperSDKProxyPushChannelSubscriptions+Private.h" + header "Ably/ARTWrapperSDKProxyPushChannel+Private.h" } } diff --git a/Source/include/Ably/ARTWrapperSDKProxyPushChannel.h b/Source/include/Ably/ARTWrapperSDKProxyPushChannel.h new file mode 100644 index 000000000..77c7f5990 --- /dev/null +++ b/Source/include/Ably/ARTWrapperSDKProxyPushChannel.h @@ -0,0 +1,18 @@ +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * An object which wraps an instance of `ARTPushChannel` and provides a similar API. It allows Ably-authored wrapper SDKs to send analytics information so that Ably can track the usage of the wrapper SDK. + * + * - Important: This class should only be used by Ably-authored SDKs. + */ +NS_SWIFT_SENDABLE +@interface ARTWrapperSDKProxyPushChannel : NSObject + +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Source/include/Ably/ARTWrapperSDKProxyRealtimeChannel.h b/Source/include/Ably/ARTWrapperSDKProxyRealtimeChannel.h index 77bad352c..a3e913b55 100644 --- a/Source/include/Ably/ARTWrapperSDKProxyRealtimeChannel.h +++ b/Source/include/Ably/ARTWrapperSDKProxyRealtimeChannel.h @@ -2,6 +2,7 @@ #import @class ARTWrapperSDKProxyRealtimeChannel; +@class ARTWrapperSDKProxyPushChannel; NS_ASSUME_NONNULL_BEGIN @@ -18,7 +19,7 @@ NS_SWIFT_SENDABLE @property (readonly) ARTRealtimePresence *presence; #if TARGET_OS_IPHONE -@property (readonly) ARTPushChannel *push; +@property (readonly) ARTWrapperSDKProxyPushChannel *push; #endif @end diff --git a/Source/include/Ably/AblyInternal.h b/Source/include/Ably/AblyInternal.h index 156f05503..dcfaa9305 100644 --- a/Source/include/Ably/AblyInternal.h +++ b/Source/include/Ably/AblyInternal.h @@ -9,3 +9,4 @@ #import #import #import +#import From d2839a85c47a913221cfd16a2ad106ee7a67cc58 Mon Sep 17 00:00:00 2001 From: Lawrence Forooghian Date: Thu, 13 Feb 2025 16:44:31 -0300 Subject: [PATCH 13/16] Insert wrapper SDK agents in push channel requests As in b006650. --- Source/ARTPushChannel.m | 53 ++++++++++--------- Source/ARTWrapperSDKProxyPushChannel.m | 22 +++++--- .../Ably/ARTPushChannel+Private.h | 21 +++++--- Test/Tests/WrapperSDKProxyTests.swift | 29 ++++++++++ 4 files changed, 83 insertions(+), 42 deletions(-) diff --git a/Source/ARTPushChannel.m b/Source/ARTPushChannel.m index 57c8207d3..f52b4bb2a 100644 --- a/Source/ARTPushChannel.m +++ b/Source/ARTPushChannel.m @@ -24,41 +24,41 @@ - (instancetype)initWithInternal:(ARTPushChannelInternal *)internal queuedDeallo } - (void)subscribeDevice { - [_internal subscribeDevice]; + [_internal subscribeDeviceWithWrapperSDKAgents:nil]; } - (void)subscribeDevice:(ARTCallback)callback { - [_internal subscribeDevice:callback]; + [_internal subscribeDeviceWithWrapperSDKAgents:nil completion:callback]; } - (void)subscribeClient { - [_internal subscribeClient]; + [_internal subscribeClientWithWrapperSDKAgents:nil]; } - (void)subscribeClient:(ARTCallback)callback { - [_internal subscribeClient:callback]; + [_internal subscribeClientWithWrapperSDKAgents:nil completion:callback]; } - (void)unsubscribeDevice { - [_internal unsubscribeDevice]; + [_internal unsubscribeDeviceWithWrapperSDKAgents:nil]; } - (void)unsubscribeDevice:(ARTCallback)callback { - [_internal unsubscribeDevice:callback]; + [_internal unsubscribeDeviceWithWrapperSDKAgents:nil completion:callback]; } - (void)unsubscribeClient { - [_internal unsubscribeClient]; + [_internal unsubscribeClientWithWrapperSDKAgents:nil]; } - (void)unsubscribeClient:(ARTCallback)callback { - [_internal unsubscribeClient:callback]; + [_internal unsubscribeClientWithWrapperSDKAgents:nil completion:callback]; } - (BOOL)listSubscriptions:(NSStringDictionary *)params callback:(ARTPaginatedPushChannelCallback)callback error:(NSError *_Nullable *_Nullable)errorPtr { - return [_internal listSubscriptions:params callback:callback error:errorPtr]; + return [_internal listSubscriptions:params wrapperSDKAgents:nil callback:callback error:errorPtr]; } @end @@ -86,23 +86,23 @@ - (instancetype)init:(ARTRestInternal *)rest withChannel:(ARTChannel *)channel l return self; } -- (void)subscribeDevice { - [self subscribeDevice:nil]; +- (void)subscribeDeviceWithWrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents { + [self subscribeDeviceWithWrapperSDKAgents:wrapperSDKAgents completion:nil]; } -- (void)unsubscribeDevice { - [self unsubscribeDevice:nil]; +- (void)unsubscribeDeviceWithWrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents { + [self unsubscribeDeviceWithWrapperSDKAgents:wrapperSDKAgents completion:nil]; } -- (void)subscribeClient { - [self subscribeClient:nil]; +- (void)subscribeClientWithWrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents { + [self subscribeClientWithWrapperSDKAgents:wrapperSDKAgents completion:nil]; } -- (void)unsubscribeClient { - [self unsubscribeClient:nil]; +- (void)unsubscribeClientWithWrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents { + [self unsubscribeClientWithWrapperSDKAgents:wrapperSDKAgents completion:nil]; } -- (void)subscribeDevice:(ARTCallback)callback { +- (void)subscribeDeviceWithWrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents completion:(ARTCallback)callback { if (callback) { ARTCallback userCallback = callback; callback = ^(ARTErrorInfo *_Nullable error) { @@ -129,7 +129,7 @@ - (void)subscribeDevice:(ARTCallback)callback { [request setDeviceAuthentication:deviceId localDevice:device]; ARTLogDebug(self->_logger, @"subscribe notifications for device %@ in channel %@", deviceId, self->_channel.name); - [self->_rest executeRequest:request withAuthOption:ARTAuthenticationOn wrapperSDKAgents:nil completion:^(NSHTTPURLResponse *response, NSData *data, NSError *error) { + [self->_rest executeRequest:request withAuthOption:ARTAuthenticationOn wrapperSDKAgents:wrapperSDKAgents completion:^(NSHTTPURLResponse *response, NSData *data, NSError *error) { if (error) { ARTLogError(self->_logger, @"%@: subscribe notifications for device %@ in channel %@ failed (%@)", NSStringFromClass(self.class), deviceId, self->_channel.name, error.localizedDescription); } @@ -138,7 +138,7 @@ - (void)subscribeDevice:(ARTCallback)callback { }); } -- (void)subscribeClient:(ARTCallback)callback { +- (void)subscribeClientWithWrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents completion:(ARTCallback)callback { if (callback) { ARTCallback userCallback = callback; callback = ^(ARTErrorInfo *_Nullable error) { @@ -163,7 +163,7 @@ - (void)subscribeClient:(ARTCallback)callback { [request setValue:[[self->_rest defaultEncoder] mimeType] forHTTPHeaderField:@"Content-Type"]; ARTLogDebug(self->_logger, @"subscribe notifications for clientId %@ in channel %@", clientId, self->_channel.name); - [self->_rest executeRequest:request withAuthOption:ARTAuthenticationOn wrapperSDKAgents:nil completion:^(NSHTTPURLResponse *response, NSData *data, NSError *error) { + [self->_rest executeRequest:request withAuthOption:ARTAuthenticationOn wrapperSDKAgents:wrapperSDKAgents completion:^(NSHTTPURLResponse *response, NSData *data, NSError *error) { if (error) { ARTLogError(self->_logger, @"%@: subscribe notifications for clientId %@ in channel %@ failed (%@)", NSStringFromClass(self.class), clientId, self->_channel.name, error.localizedDescription); } @@ -172,7 +172,7 @@ - (void)subscribeClient:(ARTCallback)callback { }); } -- (void)unsubscribeDevice:(ARTCallback)callback { +- (void)unsubscribeDeviceWithWrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents completion:(ARTCallback)callback { if (callback) { ARTCallback userCallback = callback; callback = ^(ARTErrorInfo *_Nullable error) { @@ -200,7 +200,7 @@ - (void)unsubscribeDevice:(ARTCallback)callback { [request setDeviceAuthentication:deviceId localDevice:device]; ARTLogDebug(self->_logger, @"unsubscribe notifications for device %@ in channel %@", deviceId, self->_channel.name); - [self->_rest executeRequest:request withAuthOption:ARTAuthenticationOn wrapperSDKAgents:nil completion:^(NSHTTPURLResponse *response, NSData *data, NSError *error) { + [self->_rest executeRequest:request withAuthOption:ARTAuthenticationOn wrapperSDKAgents:wrapperSDKAgents completion:^(NSHTTPURLResponse *response, NSData *data, NSError *error) { if (error) { ARTLogError(self->_logger, @"%@: unsubscribe notifications for device %@ in channel %@ failed (%@)", NSStringFromClass(self.class), deviceId, self->_channel.name, error.localizedDescription); } @@ -209,7 +209,7 @@ - (void)unsubscribeDevice:(ARTCallback)callback { }); } -- (void)unsubscribeClient:(ARTCallback)callback { +- (void)unsubscribeClientWithWrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents completion:(ARTCallback)callback { if (callback) { ARTCallback userCallback = callback; callback = ^(ARTErrorInfo *_Nullable error) { @@ -235,7 +235,7 @@ - (void)unsubscribeClient:(ARTCallback)callback { request.HTTPMethod = @"DELETE"; ARTLogDebug(self->_logger, @"unsubscribe notifications for clientId %@ in channel %@", clientId, self->_channel.name); - [self->_rest executeRequest:request withAuthOption:ARTAuthenticationOn wrapperSDKAgents:nil completion:^(NSHTTPURLResponse *response, NSData *data, NSError *error) { + [self->_rest executeRequest:request withAuthOption:ARTAuthenticationOn wrapperSDKAgents:wrapperSDKAgents completion:^(NSHTTPURLResponse *response, NSData *data, NSError *error) { if (error) { ARTLogError(self->_logger, @"%@: unsubscribe notifications for clientId %@ in channel %@ failed (%@)", NSStringFromClass(self.class), clientId, self->_channel.name, error.localizedDescription); } @@ -245,6 +245,7 @@ - (void)unsubscribeClient:(ARTCallback)callback { } - (BOOL)listSubscriptions:(NSStringDictionary *)params + wrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents callback:(ARTPaginatedPushChannelCallback)callback error:(NSError * __autoreleasing *)errorPtr { if (callback) { @@ -290,7 +291,7 @@ - (BOOL)listSubscriptions:(NSStringDictionary *)params return [self->_rest.encoders[response.MIMEType] decodePushChannelSubscriptions:data error:error]; }; - [ARTPaginatedResult executePaginated:self->_rest withRequest:request andResponseProcessor:responseProcessor wrapperSDKAgents:nil logger:self->_logger callback:callback]; + [ARTPaginatedResult executePaginated:self->_rest withRequest:request andResponseProcessor:responseProcessor wrapperSDKAgents:wrapperSDKAgents logger:self->_logger callback:callback]; ret = YES; }); return ret; diff --git a/Source/ARTWrapperSDKProxyPushChannel.m b/Source/ARTWrapperSDKProxyPushChannel.m index 216a58308..f4ae3c526 100644 --- a/Source/ARTWrapperSDKProxyPushChannel.m +++ b/Source/ARTWrapperSDKProxyPushChannel.m @@ -1,4 +1,6 @@ #import "ARTWrapperSDKProxyPushChannel+Private.h" +#import "ARTPushChannel+Private.h" +#import "ARTWrapperSDKProxyOptions.h" NS_ASSUME_NONNULL_BEGIN @@ -27,35 +29,39 @@ - (BOOL)listSubscriptions:(nonnull NSStringDictionary *)params callback:(nonnull } - (void)subscribeClient { - [self.underlyingPushChannel subscribeClient]; + [self.underlyingPushChannel.internal subscribeClientWithWrapperSDKAgents:self.proxyOptions.agents]; } - (void)subscribeClient:(nullable ARTCallback)callback { - [self.underlyingPushChannel subscribeClient:callback]; + [self.underlyingPushChannel.internal subscribeClientWithWrapperSDKAgents:self.proxyOptions.agents + completion:callback]; } - (void)subscribeDevice { - [self.underlyingPushChannel subscribeDevice]; + [self.underlyingPushChannel.internal subscribeDeviceWithWrapperSDKAgents:self.proxyOptions.agents]; } - (void)subscribeDevice:(nullable ARTCallback)callback { - [self.underlyingPushChannel subscribeDevice:callback]; + [self.underlyingPushChannel.internal subscribeDeviceWithWrapperSDKAgents:self.proxyOptions.agents + completion:callback]; } - (void)unsubscribeClient { - [self.underlyingPushChannel unsubscribeClient]; + [self.underlyingPushChannel.internal unsubscribeClientWithWrapperSDKAgents:self.proxyOptions.agents]; } - (void)unsubscribeClient:(nullable ARTCallback)callback { - [self.underlyingPushChannel unsubscribeClient:callback]; + [self.underlyingPushChannel.internal unsubscribeClientWithWrapperSDKAgents:self.proxyOptions.agents + completion:callback]; } - (void)unsubscribeDevice { - [self.underlyingPushChannel unsubscribeDevice]; + [self.underlyingPushChannel.internal unsubscribeDeviceWithWrapperSDKAgents:self.proxyOptions.agents]; } - (void)unsubscribeDevice:(nullable ARTCallback)callback { - [self.underlyingPushChannel unsubscribeDevice:callback]; + [self.underlyingPushChannel.internal unsubscribeDeviceWithWrapperSDKAgents:self.proxyOptions.agents + completion:callback]; } @end diff --git a/Source/PrivateHeaders/Ably/ARTPushChannel+Private.h b/Source/PrivateHeaders/Ably/ARTPushChannel+Private.h index 77e1d39c2..3749c5dac 100644 --- a/Source/PrivateHeaders/Ably/ARTPushChannel+Private.h +++ b/Source/PrivateHeaders/Ably/ARTPushChannel+Private.h @@ -11,23 +11,28 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)init:(ARTRestInternal *)rest withChannel:(ARTChannel *)channel logger:(ARTInternalLog *)logger; -- (void)subscribeDevice; +- (void)subscribeDeviceWithWrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents; -- (void)subscribeDevice:(nullable ARTCallback)callback; +- (void)subscribeDeviceWithWrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents + completion:(nullable ARTCallback)callback; -- (void)subscribeClient; +- (void)subscribeClientWithWrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents; -- (void)subscribeClient:(nullable ARTCallback)callback; +- (void)subscribeClientWithWrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents + completion:(nullable ARTCallback)callback; -- (void)unsubscribeDevice; +- (void)unsubscribeDeviceWithWrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents; -- (void)unsubscribeDevice:(nullable ARTCallback)callback; +- (void)unsubscribeDeviceWithWrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents + completion:(nullable ARTCallback)callback; -- (void)unsubscribeClient; +- (void)unsubscribeClientWithWrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents; -- (void)unsubscribeClient:(nullable ARTCallback)callback; +- (void)unsubscribeClientWithWrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents + completion:(nullable ARTCallback)callback; - (BOOL)listSubscriptions:(NSStringDictionary *)params + wrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents callback:(ARTPaginatedPushChannelCallback)callback error:(NSError *_Nullable *_Nullable)errorPtr; diff --git a/Test/Tests/WrapperSDKProxyTests.swift b/Test/Tests/WrapperSDKProxyTests.swift index 23e89f0c8..e6699e772 100644 --- a/Test/Tests/WrapperSDKProxyTests.swift +++ b/Test/Tests/WrapperSDKProxyTests.swift @@ -473,6 +473,35 @@ class WrapperSDKProxyTests: XCTestCase { } } +#if os(iOS) + func test_pushChannel_addsWrapperSDKAgentToRequests() throws { + let test = Test() + + // We just do a smoke test of one of the methods offered by this class + + try parameterizedTest_addsWrapperSDKAgentToRequests(test: test) { proxyClient in + // These three lines are copied from PushChannelTests + let testIdentityTokenDetails = ARTDeviceIdentityTokenDetails(token: "xxxx-xxxx-xxx", issued: Date(), expires: Date.distantFuture, capability: "", clientId: "") + proxyClient.device.setAndPersistIdentityTokenDetails(testIdentityTokenDetails) + defer { proxyClient.device.setAndPersistIdentityTokenDetails(nil) } + + let channel = proxyClient.channels.get(test.uniqueChannelName()) + + waitUntil(timeout: testTimeout) { done in + channel.push.subscribeDevice { error in + // (We expect this request to fail, because we're using a fake device token. Doesn't matter in this test, because all we care about is checking that the request contained the wrapper SDK agent) + if (error?.domain == ARTAblyErrorDomain && error?.code == 40005) { + done() + return + } + XCTAssertNil(error) + done() + } + } + } + } +#endif + // MARK: - `agent` channel param private func parameterizedTest_checkAttachProtocolMessage( From 442ebd8e7c5a9bd4ef0ee5ab3f8aff72f6408db0 Mon Sep 17 00:00:00 2001 From: Lawrence Forooghian Date: Thu, 13 Feb 2025 16:54:44 -0300 Subject: [PATCH 14/16] Create wrapper SDK proxy realtime presence As in 4daf4ba. --- Ably.xcodeproj/project.pbxproj | 24 ++++ Source/ARTWrapperSDKProxyRealtimeChannel.m | 7 +- Source/ARTWrapperSDKProxyRealtimePresence.m | 121 ++++++++++++++++++ Source/Ably.modulemap | 1 + ...TWrapperSDKProxyRealtimePresence+Private.h | 14 ++ Source/include/Ably.modulemap | 1 + .../Ably/ARTWrapperSDKProxyRealtimeChannel.h | 3 +- .../Ably/ARTWrapperSDKProxyRealtimePresence.h | 18 +++ Source/include/Ably/AblyInternal.h | 1 + 9 files changed, 185 insertions(+), 5 deletions(-) create mode 100644 Source/ARTWrapperSDKProxyRealtimePresence.m create mode 100644 Source/PrivateHeaders/Ably/ARTWrapperSDKProxyRealtimePresence+Private.h create mode 100644 Source/include/Ably/ARTWrapperSDKProxyRealtimePresence.h diff --git a/Ably.xcodeproj/project.pbxproj b/Ably.xcodeproj/project.pbxproj index 68f0da69c..fbc39234a 100644 --- a/Ably.xcodeproj/project.pbxproj +++ b/Ably.xcodeproj/project.pbxproj @@ -253,6 +253,15 @@ 215924CB2D636D50004A235C /* ARTWrapperSDKProxyPushChannel+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 215924CA2D636D50004A235C /* ARTWrapperSDKProxyPushChannel+Private.h */; settings = {ATTRIBUTES = (Private, ); }; }; 215924CC2D636D50004A235C /* ARTWrapperSDKProxyPushChannel+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 215924CA2D636D50004A235C /* ARTWrapperSDKProxyPushChannel+Private.h */; settings = {ATTRIBUTES = (Private, ); }; }; 215924CD2D636D50004A235C /* ARTWrapperSDKProxyPushChannel+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 215924CA2D636D50004A235C /* ARTWrapperSDKProxyPushChannel+Private.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 215924CF2D636DED004A235C /* ARTWrapperSDKProxyRealtimePresence.m in Sources */ = {isa = PBXBuildFile; fileRef = 215924CE2D636DED004A235C /* ARTWrapperSDKProxyRealtimePresence.m */; }; + 215924D02D636DED004A235C /* ARTWrapperSDKProxyRealtimePresence.m in Sources */ = {isa = PBXBuildFile; fileRef = 215924CE2D636DED004A235C /* ARTWrapperSDKProxyRealtimePresence.m */; }; + 215924D12D636DED004A235C /* ARTWrapperSDKProxyRealtimePresence.m in Sources */ = {isa = PBXBuildFile; fileRef = 215924CE2D636DED004A235C /* ARTWrapperSDKProxyRealtimePresence.m */; }; + 215924D32D636DF8004A235C /* ARTWrapperSDKProxyRealtimePresence.h in Headers */ = {isa = PBXBuildFile; fileRef = 215924D22D636DF8004A235C /* ARTWrapperSDKProxyRealtimePresence.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 215924D42D636DF8004A235C /* ARTWrapperSDKProxyRealtimePresence.h in Headers */ = {isa = PBXBuildFile; fileRef = 215924D22D636DF8004A235C /* ARTWrapperSDKProxyRealtimePresence.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 215924D52D636DF8004A235C /* ARTWrapperSDKProxyRealtimePresence.h in Headers */ = {isa = PBXBuildFile; fileRef = 215924D22D636DF8004A235C /* ARTWrapperSDKProxyRealtimePresence.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 215924D72D636E04004A235C /* ARTWrapperSDKProxyRealtimePresence+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 215924D62D636E04004A235C /* ARTWrapperSDKProxyRealtimePresence+Private.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 215924D82D636E04004A235C /* ARTWrapperSDKProxyRealtimePresence+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 215924D62D636E04004A235C /* ARTWrapperSDKProxyRealtimePresence+Private.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 215924D92D636E04004A235C /* ARTWrapperSDKProxyRealtimePresence+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 215924D62D636E04004A235C /* ARTWrapperSDKProxyRealtimePresence+Private.h */; settings = {ATTRIBUTES = (Private, ); }; }; 215F75F82922B1DB009E0E76 /* ARTClientInformation.h in Headers */ = {isa = PBXBuildFile; fileRef = 215F75F62922B1DB009E0E76 /* ARTClientInformation.h */; settings = {ATTRIBUTES = (Public, ); }; }; 215F75F92922B1DB009E0E76 /* ARTClientInformation.h in Headers */ = {isa = PBXBuildFile; fileRef = 215F75F62922B1DB009E0E76 /* ARTClientInformation.h */; settings = {ATTRIBUTES = (Public, ); }; }; 215F75FA2922B1DB009E0E76 /* ARTClientInformation.h in Headers */ = {isa = PBXBuildFile; fileRef = 215F75F62922B1DB009E0E76 /* ARTClientInformation.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -1301,6 +1310,9 @@ 215924C22D636D2F004A235C /* ARTWrapperSDKProxyPushChannel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ARTWrapperSDKProxyPushChannel.m; sourceTree = ""; }; 215924C62D636D43004A235C /* ARTWrapperSDKProxyPushChannel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ARTWrapperSDKProxyPushChannel.h; path = include/Ably/ARTWrapperSDKProxyPushChannel.h; sourceTree = ""; }; 215924CA2D636D50004A235C /* ARTWrapperSDKProxyPushChannel+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "ARTWrapperSDKProxyPushChannel+Private.h"; path = "PrivateHeaders/Ably/ARTWrapperSDKProxyPushChannel+Private.h"; sourceTree = ""; }; + 215924CE2D636DED004A235C /* ARTWrapperSDKProxyRealtimePresence.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ARTWrapperSDKProxyRealtimePresence.m; sourceTree = ""; }; + 215924D22D636DF8004A235C /* ARTWrapperSDKProxyRealtimePresence.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ARTWrapperSDKProxyRealtimePresence.h; path = include/Ably/ARTWrapperSDKProxyRealtimePresence.h; sourceTree = ""; }; + 215924D62D636E04004A235C /* ARTWrapperSDKProxyRealtimePresence+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "ARTWrapperSDKProxyRealtimePresence+Private.h"; path = "PrivateHeaders/Ably/ARTWrapperSDKProxyRealtimePresence+Private.h"; sourceTree = ""; }; 215F75F62922B1DB009E0E76 /* ARTClientInformation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ARTClientInformation.h; path = include/Ably/ARTClientInformation.h; sourceTree = ""; }; 215F75F72922B1DB009E0E76 /* ARTClientInformation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ARTClientInformation.m; sourceTree = ""; }; 215F75FE2922B30F009E0E76 /* ClientInformationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClientInformationTests.swift; sourceTree = ""; }; @@ -1742,6 +1754,9 @@ 215924C62D636D43004A235C /* ARTWrapperSDKProxyPushChannel.h */, 215924CA2D636D50004A235C /* ARTWrapperSDKProxyPushChannel+Private.h */, 215924C22D636D2F004A235C /* ARTWrapperSDKProxyPushChannel.m */, + 215924D22D636DF8004A235C /* ARTWrapperSDKProxyRealtimePresence.h */, + 215924D62D636E04004A235C /* ARTWrapperSDKProxyRealtimePresence+Private.h */, + 215924CE2D636DED004A235C /* ARTWrapperSDKProxyRealtimePresence.m */, ); name = "Wrapper SDK Proxy"; sourceTree = ""; @@ -2417,6 +2432,7 @@ EB2D84F71CD75CCE00F23CDA /* ARTReachability.h in Headers */, D73B655523EF2B2900D459A6 /* ARTDeltaCodec.h in Headers */, 213AEA1C2D35A6120067FD5F /* ARTWrapperSDKProxyOptions.h in Headers */, + 215924D52D636DF8004A235C /* ARTWrapperSDKProxyRealtimePresence.h in Headers */, 1C1EC3FA1AE26A8B00AAADD7 /* ARTStatus.h in Headers */, 840FCE532C875B8A001163E1 /* ARTDevicePushDetails+Private.h in Headers */, D70EAAED1BC3376200CD8B9E /* ARTRestChannel.h in Headers */, @@ -2428,6 +2444,7 @@ 2114D4312D4BCAE20032839A /* ARTRealtime+WrapperSDKProxy.h in Headers */, 96A507B51A37881C0077CDF8 /* ARTNSDate+ARTUtil.h in Headers */, D5BB211926AA9A9F00AA5F3E /* ARTNSMutableDictionary+ARTDictionaryUtil.h in Headers */, + 215924D92D636E04004A235C /* ARTWrapperSDKProxyRealtimePresence+Private.h in Headers */, 967A43211A39AEAF00E4CE23 /* ARTNSArray+ARTFunctional.h in Headers */, 21113B4529DB484200652C86 /* ARTChannel+Subclass.h in Headers */, D7C1B8791BBF5F810087B55F /* ARTAuth+Private.h in Headers */, @@ -2671,6 +2688,7 @@ 21AC0CCC2D4AA0F50030BD23 /* ARTWrapperSDKProxyRealtimeChannel+Private.h in Headers */, 21AC0CCD2D4AA0F50030BD23 /* ARTWrapperSDKProxyRealtimeChannels+Private.h in Headers */, D710D51D21949C42008F54AD /* ARTDeviceStorage.h in Headers */, + 215924D42D636DF8004A235C /* ARTWrapperSDKProxyRealtimePresence.h in Headers */, D710D60D21949DDB008F54AD /* ARTDataQuery.h in Headers */, D710D58221949D28008F54AD /* ARTTokenParams.h in Headers */, D710D51921949C42008F54AD /* ARTDeviceDetails.h in Headers */, @@ -2724,6 +2742,7 @@ D710D68A21949EDA008F54AD /* ARTNSDate+ARTUtil.h in Headers */, 215924A62D636B5C004A235C /* ARTWrapperSDKProxyPushDeviceRegistrations.h in Headers */, 215924A72D636B5C004A235C /* ARTWrapperSDKProxyPushChannelSubscriptions.h in Headers */, + 215924D72D636E04004A235C /* ARTWrapperSDKProxyRealtimePresence+Private.h in Headers */, D710D4D721949BF9008F54AD /* ARTConnectionDetails.h in Headers */, D710D4DB21949BF9008F54AD /* ARTRealtimeChannels.h in Headers */, D710D61021949DDB008F54AD /* ARTFallback.h in Headers */, @@ -2862,6 +2881,7 @@ 21AC0CCA2D4AA0F50030BD23 /* ARTWrapperSDKProxyRealtimeChannel+Private.h in Headers */, 21AC0CCB2D4AA0F50030BD23 /* ARTWrapperSDKProxyRealtimeChannels+Private.h in Headers */, D710D52F21949C44008F54AD /* ARTDeviceStorage.h in Headers */, + 215924D32D636DF8004A235C /* ARTWrapperSDKProxyRealtimePresence.h in Headers */, D710D61721949DDC008F54AD /* ARTDataQuery.h in Headers */, D710D5A821949D2A008F54AD /* ARTTokenParams.h in Headers */, D710D52B21949C44008F54AD /* ARTDeviceDetails.h in Headers */, @@ -2915,6 +2935,7 @@ D710D68C21949EDB008F54AD /* ARTNSDate+ARTUtil.h in Headers */, 215924A82D636B5C004A235C /* ARTWrapperSDKProxyPushDeviceRegistrations.h in Headers */, 215924A92D636B5C004A235C /* ARTWrapperSDKProxyPushChannelSubscriptions.h in Headers */, + 215924D82D636E04004A235C /* ARTWrapperSDKProxyRealtimePresence+Private.h in Headers */, D710D4E721949BFB008F54AD /* ARTConnectionDetails.h in Headers */, D710D4EB21949BFB008F54AD /* ARTRealtimeChannels.h in Headers */, D710D61A21949DDC008F54AD /* ARTFallback.h in Headers */, @@ -3412,6 +3433,7 @@ 96BF61711A35FB7C004CF2B3 /* ARTAuth.m in Sources */, 96E408441A38939E00087F77 /* ARTProtocolMessage.m in Sources */, D71966E51E5DF360000974DD /* ARTPushActivationStateMachine.m in Sources */, + 215924D12D636DED004A235C /* ARTWrapperSDKProxyRealtimePresence.m in Sources */, EB9121401CA0AD8200BA0A40 /* ARTMsgPackEncoder.m in Sources */, 96BF61651A35CDE1004CF2B3 /* ARTBaseMessage.m in Sources */, D7F1D3781BF4DE72001A4B5E /* ARTRealtimePresence.m in Sources */, @@ -3665,6 +3687,7 @@ D710D53221949C54008F54AD /* ARTPushChannel.m in Sources */, D710D5D421949D78008F54AD /* ARTTokenDetails.m in Sources */, D710D49B21949ACA008F54AD /* ARTRestChannels.m in Sources */, + 215924CF2D636DED004A235C /* ARTWrapperSDKProxyRealtimePresence.m in Sources */, D710D62E21949E03008F54AD /* ARTURLSessionServerTrust.m in Sources */, D710D66B21949E78008F54AD /* ARTJsonEncoder.m in Sources */, D710D5D521949D78008F54AD /* ARTClientOptions.m in Sources */, @@ -3798,6 +3821,7 @@ D710D5FA21949D79008F54AD /* ARTTokenDetails.m in Sources */, D710D4A521949ACB008F54AD /* ARTRestChannels.m in Sources */, D710D63E21949E04008F54AD /* ARTURLSessionServerTrust.m in Sources */, + 215924D02D636DED004A235C /* ARTWrapperSDKProxyRealtimePresence.m in Sources */, D710D65121949E77008F54AD /* ARTJsonEncoder.m in Sources */, D710D5FB21949D79008F54AD /* ARTClientOptions.m in Sources */, D710D5FC21949D79008F54AD /* ARTChannel.m in Sources */, diff --git a/Source/ARTWrapperSDKProxyRealtimeChannel.m b/Source/ARTWrapperSDKProxyRealtimeChannel.m index e33f2cae0..4ef6ff79a 100644 --- a/Source/ARTWrapperSDKProxyRealtimeChannel.m +++ b/Source/ARTWrapperSDKProxyRealtimeChannel.m @@ -2,6 +2,7 @@ #import "ARTRealtimeChannel+Private.h" #import "ARTWrapperSDKProxyOptions.h" #import "ARTWrapperSDKProxyPushChannel+Private.h" +#import "ARTWrapperSDKProxyRealtimePresence+Private.h" NS_ASSUME_NONNULL_BEGIN @@ -24,6 +25,8 @@ - (instancetype)initWithChannel:(ARTRealtimeChannel *)channel proxyOptions:(ARTW _push = [[ARTWrapperSDKProxyPushChannel alloc] initWithPushChannel:channel.push proxyOptions:proxyOptions]; #endif + _presence = [[ARTWrapperSDKProxyRealtimePresence alloc] initWithRealtimePresence:channel.presence + proxyOptions:proxyOptions]; } return self; @@ -41,10 +44,6 @@ - (ARTRealtimeChannelOptions *)getOptions { return self.underlyingChannel.options; } -- (id)presence { - return self.underlyingChannel.presence; -} - - (ARTChannelProperties *)properties { return self.underlyingChannel.properties; } diff --git a/Source/ARTWrapperSDKProxyRealtimePresence.m b/Source/ARTWrapperSDKProxyRealtimePresence.m new file mode 100644 index 000000000..295c66ed1 --- /dev/null +++ b/Source/ARTWrapperSDKProxyRealtimePresence.m @@ -0,0 +1,121 @@ +#import "ARTWrapperSDKProxyRealtimePresence+Private.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface ARTWrapperSDKProxyRealtimePresence () + +@property (nonatomic, readonly) ARTRealtimePresence *underlyingRealtimePresence; +@property (nonatomic, readonly) ARTWrapperSDKProxyOptions *proxyOptions; + +@end + +NS_ASSUME_NONNULL_END + +@implementation ARTWrapperSDKProxyRealtimePresence + +- (instancetype)initWithRealtimePresence:(ARTRealtimePresence *)push proxyOptions:(ARTWrapperSDKProxyOptions *)proxyOptions { + if (self = [super init]) { + _underlyingRealtimePresence = push; + _proxyOptions = proxyOptions; + } + + return self; +} + +- (BOOL)syncComplete { + return self.underlyingRealtimePresence.syncComplete; +} + +- (void)enter:(id _Nullable)data { + [self.underlyingRealtimePresence enter:data]; +} + +- (void)enter:(id _Nullable)data callback:(nullable ARTCallback)callback { + [self.underlyingRealtimePresence enter:data callback:callback]; +} + +- (void)enterClient:(nonnull NSString *)clientId data:(id _Nullable)data { + [self.underlyingRealtimePresence enterClient:clientId data:data]; +} + +- (void)enterClient:(nonnull NSString *)clientId data:(id _Nullable)data callback:(nullable ARTCallback)callback { + [self.underlyingRealtimePresence enterClient:clientId data:data callback:callback]; +} + +- (void)get:(nonnull ARTPresenceMessagesCallback)callback { + [self.underlyingRealtimePresence get:callback]; +} + +- (void)get:(nonnull ARTRealtimePresenceQuery *)query callback:(nonnull ARTPresenceMessagesCallback)callback { + [self.underlyingRealtimePresence get:query callback:callback]; +} + +- (void)history:(nonnull ARTPaginatedPresenceCallback)callback { + [self.underlyingRealtimePresence history:callback]; +} + +- (BOOL)history:(ARTRealtimeHistoryQuery * _Nullable)query callback:(nonnull ARTPaginatedPresenceCallback)callback error:(NSError * _Nullable __autoreleasing * _Nullable)errorPtr { + return [self.underlyingRealtimePresence history:query callback:callback error:errorPtr]; +} + +- (void)leave:(id _Nullable)data { + [self.underlyingRealtimePresence leave:data]; +} + +- (void)leave:(id _Nullable)data callback:(nullable ARTCallback)callback { + [self.underlyingRealtimePresence leave:data callback:callback]; +} + +- (void)leaveClient:(nonnull NSString *)clientId data:(id _Nullable)data { + [self.underlyingRealtimePresence leaveClient:clientId data:data]; +} + +- (void)leaveClient:(nonnull NSString *)clientId data:(id _Nullable)data callback:(nullable ARTCallback)callback { + [self.underlyingRealtimePresence leaveClient:clientId data:data callback:callback]; +} + +- (ARTEventListener * _Nullable)subscribe:(nonnull ARTPresenceMessageCallback)callback { + return [self.underlyingRealtimePresence subscribe:callback]; +} + +- (ARTEventListener * _Nullable)subscribe:(ARTPresenceAction)action callback:(nonnull ARTPresenceMessageCallback)callback { + return [self.underlyingRealtimePresence subscribe:action callback:callback]; +} + +- (ARTEventListener * _Nullable)subscribe:(ARTPresenceAction)action onAttach:(nullable ARTCallback)onAttach callback:(nonnull ARTPresenceMessageCallback)callback { + return [self.underlyingRealtimePresence subscribe:action onAttach:onAttach callback:callback]; +} + +- (ARTEventListener * _Nullable)subscribeWithAttachCallback:(nullable ARTCallback)onAttach callback:(nonnull ARTPresenceMessageCallback)callback { + return [self.underlyingRealtimePresence subscribeWithAttachCallback:onAttach callback:callback]; +} + +- (void)unsubscribe { + [self.underlyingRealtimePresence unsubscribe]; +} + +- (void)unsubscribe:(nonnull ARTEventListener *)listener { + [self.underlyingRealtimePresence unsubscribe:listener]; +} + +- (void)unsubscribe:(ARTPresenceAction)action listener:(nonnull ARTEventListener *)listener { + [self.underlyingRealtimePresence unsubscribe:action listener:listener]; +} + +- (void)update:(id _Nullable)data { + [self.underlyingRealtimePresence update:data]; +} + +- (void)update:(id _Nullable)data callback:(nullable ARTCallback)callback { + [self.underlyingRealtimePresence update:data callback:callback]; +} + +- (void)updateClient:(nonnull NSString *)clientId data:(id _Nullable)data { + [self.underlyingRealtimePresence updateClient:clientId data:data]; +} + +- (void)updateClient:(nonnull NSString *)clientId data:(id _Nullable)data callback:(nullable ARTCallback)callback { + [self.underlyingRealtimePresence updateClient:clientId data:data callback:callback]; +} + +@end diff --git a/Source/Ably.modulemap b/Source/Ably.modulemap index 32c6eb4ad..17378bfcd 100644 --- a/Source/Ably.modulemap +++ b/Source/Ably.modulemap @@ -121,5 +121,6 @@ framework module Ably { header "ARTWrapperSDKProxyPushDeviceRegistrations+Private.h" header "ARTWrapperSDKProxyPushChannelSubscriptions+Private.h" header "ARTWrapperSDKProxyPushChannel+Private.h" + header "ARTWrapperSDKProxyRealtimePresence+Private.h" } } diff --git a/Source/PrivateHeaders/Ably/ARTWrapperSDKProxyRealtimePresence+Private.h b/Source/PrivateHeaders/Ably/ARTWrapperSDKProxyRealtimePresence+Private.h new file mode 100644 index 000000000..bc95af9d0 --- /dev/null +++ b/Source/PrivateHeaders/Ably/ARTWrapperSDKProxyRealtimePresence+Private.h @@ -0,0 +1,14 @@ +#import + +@class ARTWrapperSDKProxyOptions; + +NS_ASSUME_NONNULL_BEGIN + +@interface ARTWrapperSDKProxyRealtimePresence () + +- (instancetype)initWithRealtimePresence:(ARTRealtimePresence *)realtimePresence + proxyOptions:(ARTWrapperSDKProxyOptions *)proxyOptions NS_DESIGNATED_INITIALIZER; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Source/include/Ably.modulemap b/Source/include/Ably.modulemap index 4019339d1..bff4a2c6c 100644 --- a/Source/include/Ably.modulemap +++ b/Source/include/Ably.modulemap @@ -119,5 +119,6 @@ framework module Ably { header "Ably/ARTWrapperSDKProxyPushDeviceRegistrations+Private.h" header "Ably/ARTWrapperSDKProxyPushChannelSubscriptions+Private.h" header "Ably/ARTWrapperSDKProxyPushChannel+Private.h" + header "Ably/ARTWrapperSDKProxyRealtimePresence+Private.h" } } diff --git a/Source/include/Ably/ARTWrapperSDKProxyRealtimeChannel.h b/Source/include/Ably/ARTWrapperSDKProxyRealtimeChannel.h index a3e913b55..c91c0e489 100644 --- a/Source/include/Ably/ARTWrapperSDKProxyRealtimeChannel.h +++ b/Source/include/Ably/ARTWrapperSDKProxyRealtimeChannel.h @@ -3,6 +3,7 @@ @class ARTWrapperSDKProxyRealtimeChannel; @class ARTWrapperSDKProxyPushChannel; +@class ARTWrapperSDKProxyRealtimePresence; NS_ASSUME_NONNULL_BEGIN @@ -16,7 +17,7 @@ NS_SWIFT_SENDABLE - (instancetype)init NS_UNAVAILABLE; -@property (readonly) ARTRealtimePresence *presence; +@property (readonly) ARTWrapperSDKProxyRealtimePresence *presence; #if TARGET_OS_IPHONE @property (readonly) ARTWrapperSDKProxyPushChannel *push; diff --git a/Source/include/Ably/ARTWrapperSDKProxyRealtimePresence.h b/Source/include/Ably/ARTWrapperSDKProxyRealtimePresence.h new file mode 100644 index 000000000..81a3b6af3 --- /dev/null +++ b/Source/include/Ably/ARTWrapperSDKProxyRealtimePresence.h @@ -0,0 +1,18 @@ +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * An object which wraps an instance of `ARTRealtimePresence` and provides a similar API. It allows Ably-authored wrapper SDKs to send analytics information so that Ably can track the usage of the wrapper SDK. + * + * - Important: This class should only be used by Ably-authored SDKs. + */ +NS_SWIFT_SENDABLE +@interface ARTWrapperSDKProxyRealtimePresence : NSObject + +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Source/include/Ably/AblyInternal.h b/Source/include/Ably/AblyInternal.h index dcfaa9305..ffda1a39a 100644 --- a/Source/include/Ably/AblyInternal.h +++ b/Source/include/Ably/AblyInternal.h @@ -10,3 +10,4 @@ #import #import #import +#import From 7b25aa72f34836c08e3291c567008675c9ec9811 Mon Sep 17 00:00:00 2001 From: Lawrence Forooghian Date: Thu, 13 Feb 2025 19:39:17 -0300 Subject: [PATCH 15/16] Remove ARTPresence inheritance from ARTRestPresenceInternal Motivation as in 8796ec8. --- Source/PrivateHeaders/Ably/ARTRestPresence+Private.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Source/PrivateHeaders/Ably/ARTRestPresence+Private.h b/Source/PrivateHeaders/Ably/ARTRestPresence+Private.h index 532da5816..c62fa0aa8 100644 --- a/Source/PrivateHeaders/Ably/ARTRestPresence+Private.h +++ b/Source/PrivateHeaders/Ably/ARTRestPresence+Private.h @@ -6,7 +6,7 @@ NS_ASSUME_NONNULL_BEGIN @class ARTRestChannelInternal; @class ARTInternalLog; -@interface ARTRestPresenceInternal : ARTPresence +@interface ARTRestPresenceInternal : NSObject - (instancetype)initWithChannel:(ARTRestChannelInternal *)channel logger:(ARTInternalLog *)logger; @@ -18,6 +18,8 @@ NS_ASSUME_NONNULL_BEGIN - (BOOL)history:(nullable ARTDataQuery *)query callback:(ARTPaginatedPresenceCallback)callback error:(NSError *_Nullable *_Nullable)errorPtr; +- (void)history:(ARTPaginatedPresenceCallback)callback; + @end @interface ARTRestPresence () From d7c0bc1862301e8974e43d5a6529bcd2a51df1e0 Mon Sep 17 00:00:00 2001 From: Lawrence Forooghian Date: Thu, 13 Feb 2025 19:28:10 -0300 Subject: [PATCH 16/16] Insert wrapper SDK agents in realtime presence history requests As in b006650. Resolves #2029. --- Source/ARTRealtimePresence.m | 13 +++++++------ Source/ARTRestPresence.m | 13 +++++++------ Source/ARTWrapperSDKProxyRealtimePresence.m | 10 ++++++++-- .../Ably/ARTRealtimePresence+Private.h | 5 +++-- .../PrivateHeaders/Ably/ARTRestPresence+Private.h | 5 +++-- Test/Tests/RealtimeClientPresenceTests.swift | 4 ++-- Test/Tests/WrapperSDKProxyTests.swift | 15 +++++++++++++++ 7 files changed, 45 insertions(+), 20 deletions(-) diff --git a/Source/ARTRealtimePresence.m b/Source/ARTRealtimePresence.m index aa5770e8c..391477ad1 100644 --- a/Source/ARTRealtimePresence.m +++ b/Source/ARTRealtimePresence.m @@ -134,11 +134,11 @@ - (void)unsubscribe:(ARTPresenceAction)action listener:(ARTEventListener *)liste } - (void)history:(ARTPaginatedPresenceCallback)callback { - [_internal history:callback]; + [_internal historyWithWrapperSDKAgents:nil completion:callback]; } - (BOOL)history:(ARTRealtimeHistoryQuery *_Nullable)query callback:(ARTPaginatedPresenceCallback)callback error:(NSError *_Nullable *_Nullable)errorPtr { - return [_internal history:query callback:callback error:errorPtr]; + return [_internal history:query wrapperSDKAgents:nil callback:callback error:errorPtr]; } @end @@ -272,13 +272,14 @@ - (void)get:(ARTRealtimePresenceQuery *)query callback:(ARTPresenceMessagesCallb // RTP12 -- (void)history:(ARTPaginatedPresenceCallback)callback { - [self history:[[ARTRealtimeHistoryQuery alloc] init] callback:callback error:nil]; +- (void)historyWithWrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents + completion:(ARTPaginatedPresenceCallback)callback { + [self history:[[ARTRealtimeHistoryQuery alloc] init] wrapperSDKAgents:wrapperSDKAgents callback:callback error:nil]; } -- (BOOL)history:(ARTRealtimeHistoryQuery *)query callback:(ARTPaginatedPresenceCallback)callback error:(NSError **)errorPtr { +- (BOOL)history:(ARTRealtimeHistoryQuery *)query wrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents callback:(ARTPaginatedPresenceCallback)callback error:(NSError **)errorPtr { query.realtimeChannel = _channel; - return [_channel.restChannel.presence history:query callback:callback error:errorPtr]; + return [_channel.restChannel.presence history:query wrapperSDKAgents:wrapperSDKAgents callback:callback error:errorPtr]; } // RTP8 diff --git a/Source/ARTRestPresence.m b/Source/ARTRestPresence.m index e113764b5..9a596acbd 100644 --- a/Source/ARTRestPresence.m +++ b/Source/ARTRestPresence.m @@ -77,11 +77,11 @@ - (BOOL)get:(ARTPresenceQuery *)query callback:(ARTPaginatedPresenceCallback)cal } - (BOOL)history:(nullable ARTDataQuery *)query callback:(ARTPaginatedPresenceCallback)callback error:(NSError *_Nullable *_Nullable)errorPtr { - return [_internal history:query callback:callback error:errorPtr]; + return [_internal history:query wrapperSDKAgents:nil callback:callback error:errorPtr]; } - (void)history:(ARTPaginatedPresenceCallback)callback { - [_internal history:callback]; + [_internal historyWithWrapperSDKAgents:nil completion:callback]; } @end @@ -161,11 +161,12 @@ - (BOOL)get:(ARTPresenceQuery *)query callback:(ARTPaginatedPresenceCallback)cal return YES; } -- (void)history:(ARTPaginatedPresenceCallback)callback { - [self history:[[ARTDataQuery alloc] init] callback:callback error:nil]; +- (void)historyWithWrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents + completion:(ARTPaginatedPresenceCallback)callback { + [self history:[[ARTDataQuery alloc] init] wrapperSDKAgents:wrapperSDKAgents callback:callback error:nil]; } -- (BOOL)history:(ARTDataQuery *)query callback:(ARTPaginatedPresenceCallback)callback error:(NSError **)errorPtr { +- (BOOL)history:(ARTDataQuery *)query wrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents callback:(ARTPaginatedPresenceCallback)callback error:(NSError **)errorPtr { if (callback) { void (^userCallback)(ARTPaginatedResult *result, ARTErrorInfo *error) = callback; callback = ^(ARTPaginatedResult *result, ARTErrorInfo *error) { @@ -217,7 +218,7 @@ - (BOOL)history:(ARTDataQuery *)query callback:(ARTPaginatedPresenceCallback)cal }; dispatch_async(_queue, ^{ - [ARTPaginatedResult executePaginated:self->_channel.rest withRequest:request andResponseProcessor:responseProcessor wrapperSDKAgents:nil logger:self->_logger callback:callback]; + [ARTPaginatedResult executePaginated:self->_channel.rest withRequest:request andResponseProcessor:responseProcessor wrapperSDKAgents:wrapperSDKAgents logger:self->_logger callback:callback]; }); return YES; } diff --git a/Source/ARTWrapperSDKProxyRealtimePresence.m b/Source/ARTWrapperSDKProxyRealtimePresence.m index 295c66ed1..b97334303 100644 --- a/Source/ARTWrapperSDKProxyRealtimePresence.m +++ b/Source/ARTWrapperSDKProxyRealtimePresence.m @@ -1,4 +1,6 @@ #import "ARTWrapperSDKProxyRealtimePresence+Private.h" +#import "ARTRealtimePresence+Private.h" +#import "ARTWrapperSDKProxyOptions.h" NS_ASSUME_NONNULL_BEGIN @@ -51,11 +53,15 @@ - (void)get:(nonnull ARTRealtimePresenceQuery *)query callback:(nonnull ARTPrese } - (void)history:(nonnull ARTPaginatedPresenceCallback)callback { - [self.underlyingRealtimePresence history:callback]; + [self.underlyingRealtimePresence.internal historyWithWrapperSDKAgents:self.proxyOptions.agents + completion:callback]; } - (BOOL)history:(ARTRealtimeHistoryQuery * _Nullable)query callback:(nonnull ARTPaginatedPresenceCallback)callback error:(NSError * _Nullable __autoreleasing * _Nullable)errorPtr { - return [self.underlyingRealtimePresence history:query callback:callback error:errorPtr]; + return [self.underlyingRealtimePresence.internal history:query + wrapperSDKAgents:self.proxyOptions.agents + callback:callback + error:errorPtr]; } - (void)leave:(id _Nullable)data { diff --git a/Source/PrivateHeaders/Ably/ARTRealtimePresence+Private.h b/Source/PrivateHeaders/Ably/ARTRealtimePresence+Private.h index 67d5cd9e0..4db24bb38 100644 --- a/Source/PrivateHeaders/Ably/ARTRealtimePresence+Private.h +++ b/Source/PrivateHeaders/Ably/ARTRealtimePresence+Private.h @@ -67,9 +67,10 @@ NS_ASSUME_NONNULL_BEGIN - (void)unsubscribe:(ARTPresenceAction)action listener:(ARTEventListener *)listener; -- (void)history:(ARTPaginatedPresenceCallback)callback; +- (void)historyWithWrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents + completion:(ARTPaginatedPresenceCallback)callback; -- (BOOL)history:(ARTRealtimeHistoryQuery *_Nullable)query callback:(ARTPaginatedPresenceCallback)callback error:(NSError *_Nullable *_Nullable)errorPtr; +- (BOOL)history:(ARTRealtimeHistoryQuery *_Nullable)query wrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents callback:(ARTPaginatedPresenceCallback)callback error:(NSError *_Nullable *_Nullable)errorPtr; @end diff --git a/Source/PrivateHeaders/Ably/ARTRestPresence+Private.h b/Source/PrivateHeaders/Ably/ARTRestPresence+Private.h index c62fa0aa8..9d99d641c 100644 --- a/Source/PrivateHeaders/Ably/ARTRestPresence+Private.h +++ b/Source/PrivateHeaders/Ably/ARTRestPresence+Private.h @@ -16,9 +16,10 @@ NS_ASSUME_NONNULL_BEGIN - (BOOL)get:(ARTPresenceQuery *)query callback:(ARTPaginatedPresenceCallback)callback error:(NSError *_Nullable *_Nullable)errorPtr; -- (BOOL)history:(nullable ARTDataQuery *)query callback:(ARTPaginatedPresenceCallback)callback error:(NSError *_Nullable *_Nullable)errorPtr; +- (BOOL)history:(nullable ARTDataQuery *)query wrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents callback:(ARTPaginatedPresenceCallback)callback error:(NSError *_Nullable *_Nullable)errorPtr; -- (void)history:(ARTPaginatedPresenceCallback)callback; +- (void)historyWithWrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents + completion:(ARTPaginatedPresenceCallback)callback; @end diff --git a/Test/Tests/RealtimeClientPresenceTests.swift b/Test/Tests/RealtimeClientPresenceTests.swift index 916b6f70b..167e40839 100644 --- a/Test/Tests/RealtimeClientPresenceTests.swift +++ b/Test/Tests/RealtimeClientPresenceTests.swift @@ -3569,12 +3569,12 @@ class RealtimeClientPresenceTests: XCTestCase { var restPresenceHistoryMethodWasCalled = false - let hookRest = channelRest.presence.internal.testSuite_injectIntoMethod(after: #selector(ARTRestPresenceInternal.history(_:callback:))) { + let hookRest = channelRest.presence.internal.testSuite_injectIntoMethod(after: #selector(ARTRestPresenceInternal.history(_:wrapperSDKAgents:callback:))) { restPresenceHistoryMethodWasCalled = true } defer { hookRest.remove() } - let hookRealtime = channelRealtime.presence.internal.testSuite_injectIntoMethod(after: #selector(ARTRestPresenceInternal.history(_:callback:))) { + let hookRealtime = channelRealtime.presence.internal.testSuite_injectIntoMethod(after: #selector(ARTRestPresenceInternal.history(_:wrapperSDKAgents:callback:))) { restPresenceHistoryMethodWasCalled = true } defer { hookRealtime.remove() } diff --git a/Test/Tests/WrapperSDKProxyTests.swift b/Test/Tests/WrapperSDKProxyTests.swift index e6699e772..46dcea79e 100644 --- a/Test/Tests/WrapperSDKProxyTests.swift +++ b/Test/Tests/WrapperSDKProxyTests.swift @@ -502,6 +502,21 @@ class WrapperSDKProxyTests: XCTestCase { } #endif + func test_presenceHistory_addsWrapperSDKAgentToRequest() throws { + let test = Test() + + try parameterizedTest_addsWrapperSDKAgentToRequests(test: test) { proxyClient in + let channel = proxyClient.channels.get(test.uniqueChannelName()) + + waitUntil(timeout: testTimeout) { done in + channel.presence.history() { _, error in + XCTAssertNil(error) + done() + } + } + } + } + // MARK: - `agent` channel param private func parameterizedTest_checkAttachProtocolMessage(