├── Source ├── ARTChannelProtocol.m ├── PrivateHeaders │ └── Ably │ │ ├── ARTSRWebSocket.h │ │ ├── ARTOSReachability.h │ │ ├── ARTJsonEncoder.h │ │ ├── ARTMsgPackEncoder.h │ │ ├── ARTNSArray+ARTFunctional.h │ │ ├── ARTChannelOptions+Private.h │ │ ├── ARTHttp+Private.h │ │ ├── ARTAuthOptions+Private.h │ │ ├── ARTConstants.h │ │ ├── ARTTokenParams+Private.h │ │ ├── ARTNSHTTPURLResponse+ARTPaginated.h │ │ ├── ARTNSURL+ARTUtils.h │ │ ├── ARTInternalLog+Testing.h │ │ ├── ARTMessageOperation+Private.h │ │ ├── ARTNSString+ARTUtil.h │ │ ├── ARTQueuedDealloc.h │ │ ├── ARTNSDate+ARTUtil.h │ │ ├── ARTFallbackHosts.h │ │ ├── ARTStringifiable+Private.h │ │ ├── ARTFallback+Private.h │ │ ├── ARTNSMutableURLRequest+ARTPaginated.h │ │ ├── ARTURLSessionServerTrust.h │ │ ├── ARTFormEncode.h │ │ ├── ARTNSError+ARTUtils.h │ │ ├── NSURLQueryItem+Stringifiable.h │ │ ├── ARTErrorInfo+Private.h │ │ ├── ARTNSMutableRequest+ARTRest.h │ │ ├── ARTDefault+Private.h │ │ ├── ARTPaginatedResult+Subclass.h │ │ ├── ARTNSMutableDictionary+ARTDictionaryUtil.h │ │ ├── ARTPresence+Private.h │ │ ├── ARTInternalLogCore+Testing.h │ │ ├── ARTReachability.h │ │ ├── ARTWrapperSDKProxyPush+Private.h │ │ ├── ARTDeviceIdentityTokenDetails+Private.h │ │ ├── ARTLocalDeviceStorage.h │ │ ├── ARTLogAdapter+Testing.h │ │ ├── ARTWrapperSDKProxyRealtime+Private.h │ │ ├── ARTWrapperSDKProxyPushAdmin+Private.h │ │ ├── ARTURLSession.h │ │ ├── ARTWrapperSDKProxyPushChannel+Private.h │ │ ├── ARTWrapperSDKProxyRealtimeChannel+Private.h │ │ ├── ARTDevicePushDetails+Private.h │ │ ├── ARTWrapperSDKProxyRealtimeChannels+Private.h │ │ ├── ARTDataQuery+Private.h │ │ ├── ARTWrapperSDKProxyRealtimePresence+Private.h │ │ ├── ARTMessageVersion+Private.h │ │ ├── ARTPublicRealtimeChannelUnderlyingObjects.h │ │ ├── ARTWrapperSDKProxyRealtimeAnnotations+Private.h │ │ ├── ARTMessageAnnotations+Private.h │ │ ├── ARTWrapperSDKProxyPushDeviceRegistrations+Private.h │ │ ├── ARTAnnotation+Private.h │ │ ├── ARTWrapperSDKProxyPushChannelSubscriptions+Private.h │ │ ├── ARTBaseMessage+Private.h │ │ ├── ARTNSMutableURLRequest+ARTUtils.h │ │ ├── ARTPresenceMessage+Private.h │ │ ├── ARTClientInformation+Private.h │ │ ├── ARTPendingMessage.h │ │ ├── ARTDeviceStorage.h │ │ ├── ARTConnectionDetails+Private.h │ │ ├── ARTDeviceDetails+Private.h │ │ ├── ARTPluginDecodingContext.h │ │ ├── ARTWebSocketFactory.h │ │ ├── ARTRestAnnotations+Private.h │ │ ├── ARTNSDictionary+ARTDictionaryUtil.h │ │ ├── ARTNSMutableRequest+ARTPush.h │ │ ├── ARTClientOptions+TestConfiguration.h │ │ ├── ARTWebSocketTransport.h │ │ ├── ARTFallback.h │ │ ├── ARTPluginAPI.h │ │ ├── ARTLog+Private.h │ │ ├── ARTHttp.h │ │ ├── ARTMessage+Private.h │ │ ├── ARTQueuedMessage.h │ │ ├── ARTJitterCoefficientGenerator.h │ │ ├── ARTErrorChecker.h │ │ ├── ARTRealtimeAnnotations+Private.h │ │ ├── ARTBackoffRetryDelayCalculator.h │ │ ├── ARTRealtimeTransportFactory.h │ │ ├── ARTRetryDelayCalculator.h │ │ ├── ARTPushAdmin+Private.h │ │ ├── ARTChannel+Private.h │ │ ├── ARTChannels+Private.h │ │ ├── ARTRestChannels+Private.h │ │ ├── ARTDictionarySerializable.h │ │ ├── ARTAttachRetryState.h │ │ ├── ARTConnectRetryState.h │ │ ├── ARTPushActivationStateMachine.h │ │ ├── ARTGCD.h │ │ ├── ARTContinuousClock.h │ │ ├── ARTLogAdapter.h │ │ ├── ARTConnectionStateChangeParams.h │ │ ├── ARTVersion2Log.h │ │ ├── ARTProtocolMessage+Private.h │ │ ├── ARTRestPresence+Private.h │ │ ├── ARTPushActivationStateMachine+Private.h │ │ ├── ARTPushChannelSubscriptions+Private.h │ │ ├── ARTWebSocketTransport+Private.h │ │ ├── ARTPushDeviceRegistrations+Private.h │ │ └── ARTCrypto+Private.h ├── ARTConstants.m ├── ARTPresence.m ├── ARTJitterCoefficientGenerator.m ├── ARTNSMutableDictionary+ARTDictionaryUtil.m ├── ARTWrapperSDKProxyOptions.m ├── ARTPendingMessage.m ├── ARTWebSocketFactory.m ├── ARTNSURL+ARTUtils.m ├── NSURLQueryItem+Stringifiable.m ├── include │ └── Ably │ │ ├── ARTPresence.h │ │ ├── Ably.h │ │ ├── ARTAuthDetails.h │ │ ├── ARTStringifiable.h │ │ ├── ARTMessageAnnotations.h │ │ ├── ARTWrapperSDKProxyPushChannel.h │ │ ├── ARTWrapperSDKProxyRealtimePresence.h │ │ ├── ARTRealtime+WrapperSDKProxy.h │ │ ├── ARTWrapperSDKProxyRealtimeAnnotations.h │ │ ├── ARTWrapperSDKProxyPushDeviceRegistrations.h │ │ ├── ARTWrapperSDKProxyPushChannelSubscriptions.h │ │ ├── ARTWrapperSDKProxyPush.h │ │ ├── ARTLocalDevice.h │ │ ├── AblyInternal.h │ │ ├── ARTWrapperSDKProxyOptions.h │ │ ├── ARTWrapperSDKProxyRealtimeChannels.h │ │ ├── ARTDevicePushDetails.h │ │ ├── ARTMessageOperation.h │ │ ├── ARTMessageVersion.h │ │ ├── ARTWrapperSDKProxyPushAdmin.h │ │ ├── ARTWrapperSDKProxyRealtime.h │ │ ├── ARTRestChannels.h │ │ ├── ARTChannelOptions.h │ │ ├── ARTRealtimeChannels.h │ │ ├── ARTDeviceIdentityTokenDetails.h │ │ ├── ARTWrapperSDKProxyRealtimeChannel.h │ │ └── ARTPushAdmin.h ├── ARTErrorChecker.m ├── ARTNSString+ARTUtil.m ├── ARTQueuedDealloc.m ├── SocketRocket │ ├── Internal │ │ ├── Utilities │ │ │ ├── ARTSRRandom.h │ │ │ ├── ARTSRHash.h │ │ │ ├── ARTSRSIMDHelpers.h │ │ │ ├── ARTSRMutex.h │ │ │ ├── ARTSRRandom.m │ │ │ ├── ARTSRHTTPConnectMessage.h │ │ │ ├── ARTSRError.h │ │ │ ├── ARTSRLog.h │ │ │ ├── ARTSRURLUtilities.h │ │ │ ├── ARTSRMutex.m │ │ │ └── ARTSRHash.m │ │ ├── NSRunLoop+ARTSRWebSocketPrivate.h │ │ ├── NSURLRequest+ARTSRWebSocketPrivate.h │ │ ├── ARTSRConstants.m │ │ ├── RunLoop │ │ │ └── ARTSRRunLoopThread.h │ │ ├── ARTSRConstants.h │ │ ├── Proxy │ │ │ └── ARTSRProxyConnect.h │ │ ├── Security │ │ │ └── ARTSRPinningSecurityPolicy.h │ │ └── IOConsumer │ │ │ ├── ARTSRIOConsumerPool.h │ │ │ └── ARTSRIOConsumer.m │ ├── NSRunLoop+ARTSRWebSocket.h │ ├── NSRunLoop+ARTSRWebSocket.m │ ├── NSURLRequest+ARTSRWebSocket.m │ └── NSURLRequest+ARTSRWebSocket.h ├── ARTPublicRealtimeChannelUnderlyingObjects.m ├── ARTMsgPackEncoder.m ├── ARTNSError+ARTUtils.m ├── ARTNSArray+ARTFunctional.m ├── ARTAuthDetails.m ├── ARTConnectionStateChangeParams.m ├── ARTNSDate+ARTUtil.m ├── ARTNSMutableURLRequest+ARTPaginated.m ├── ARTAttachRequestParams.m ├── ARTLogAdapter.m ├── ARTNSMutableRequest+ARTRest.m ├── Info-tvOS.plist ├── ARTRealtimeTransportFactory.m ├── ARTDevicePushDetails.m ├── ARTPluginDecodingContext.m ├── Info-macOS.plist ├── ARTFallbackHosts.m ├── ARTNSMutableURLRequest+ARTUtils.m ├── PrivacyInfo.xcprivacy ├── ARTChannelStateChangeParams.m ├── ARTStringifiable.m ├── ARTJsonEncoder.m ├── ARTTestClientOptions.m ├── ARTMessageAnnotations.m ├── ARTFallback.m ├── ARTConnectionDetails.m ├── ARTNSHTTPURLResponse+ARTPaginated.m ├── ARTInternalLogCore.m ├── ARTBackoffRetryDelayCalculator.m └── ARTChannelOptions.m ├── .tool-versions ├── Ably.xcconfig ├── Version.xcconfig ├── COPYRIGHT ├── Examples ├── SPM │ ├── Sources │ │ └── SPMIntegration │ │ │ └── main.swift │ ├── .gitignore │ ├── Tests │ │ └── SPMTests │ │ │ └── SPMTests.swift │ ├── Package.resolved │ └── Package.swift ├── AblyCarthage │ ├── Cartfile │ └── AblyCarthage │ │ ├── Assets.xcassets │ │ ├── Contents.json │ │ └── AccentColor.colorset │ │ │ └── Contents.json │ │ ├── ViewController.swift │ │ └── AppDelegate.swift ├── AblyPush │ ├── AblyPushExample │ │ ├── Assets.xcassets │ │ │ ├── Contents.json │ │ │ ├── AccentColor.colorset │ │ │ │ └── Contents.json │ │ │ ├── push-enabled.imageset │ │ │ │ └── Contents.json │ │ │ ├── push-disabled.imageset │ │ │ │ └── Contents.json │ │ │ └── ably-logo.imageset │ │ │ │ └── Contents.json │ │ ├── Preview Content │ │ │ └── Preview Assets.xcassets │ │ │ │ └── Contents.json │ │ ├── Info.plist │ │ ├── InfoLP.plist │ │ ├── Buttons │ │ │ └── VerticalLabelStyle.swift │ │ ├── AblyPushExample.entitlements │ │ └── App.swift │ └── AblyLocationPush │ │ ├── AblyLocationPush.entitlements │ │ └── Info.plist ├── .gitignore └── Tests │ ├── Podfile │ ├── Tests │ └── ViewController.swift │ └── TestsTests │ └── Info.plist ├── MAINTAINERS.md ├── Cartfile ├── images └── CocoaSDK-github.png ├── Cartfile.resolved ├── fastlane ├── Pluginfile └── Scanfile ├── Scripts ├── version-constants.sh ├── get-version.sh ├── log-environment-information.sh ├── jazzy.sh ├── add-licenses-to-carthage-output.sh ├── local_dev_upload_test_results.sh ├── carthage-with-workaround-for-issue-3019.sh └── set-version.sh ├── .gitmodules ├── Ably-SoakTest-App ├── Assets.xcassets │ └── Contents.json ├── ViewController.swift └── AppDelegate.swift ├── Test ├── AblyTestingObjC │ └── include │ │ └── AblyTestingObjC.h ├── AblyTests │ ├── Test Utilities │ │ ├── MockErrorChecker.swift │ │ ├── MockVersion2Log.swift │ │ ├── NSObject+TestSuite.swift │ │ ├── BackoffCoefficients.swift │ │ ├── MockRetryDelayCalculator.swift │ │ ├── Test.swift │ │ ├── StaticJitterCoefficients.swift │ │ ├── TestProxyTransportFactory.swift │ │ └── MockJitterCoefficientGenerator.swift │ ├── Tests │ │ ├── ARTDefaultTests.swift │ │ ├── DefaultJitterCoefficientGeneratorTests.swift │ │ ├── ContinuousClockTests.swift │ │ ├── BackoffRetryDelayCalculatorTests.swift │ │ ├── RetrySequenceTests.swift │ │ └── GCDTests.swift │ └── Codables │ │ └── CryptoData.swift ├── AblyTestsObjC │ └── ObjcppTest.mm ├── Ably.xctestplan └── AblyTesting │ └── MockInternalLogCore.swift ├── Ably.xcodeproj └── project.xcworkspace │ └── contents.xcworkspacedata ├── .github ├── workflows │ ├── features.yml │ ├── check-spm.yaml │ └── docs.yml └── issue_template.md ├── Gemfile ├── Ably.xcworkspace └── contents.xcworkspacedata ├── Ably-SoakTest-AppUITests ├── Info.plist └── SoakTestReachability.swift ├── Docs └── Main.md ├── .gitignore └── Ably.podspec /Source/ARTChannelProtocol.m: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.tool-versions: -------------------------------------------------------------------------------- 1 | ruby 3.3.9 2 | -------------------------------------------------------------------------------- /Ably.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Version.xcconfig" 2 | -------------------------------------------------------------------------------- /Version.xcconfig: -------------------------------------------------------------------------------- 1 | CURRENT_PROJECT_VERSION = 1.2.55 2 | -------------------------------------------------------------------------------- /COPYRIGHT: -------------------------------------------------------------------------------- 1 | Copyright 2015-2022 Ably Real-time Ltd (ably.com) 2 | -------------------------------------------------------------------------------- /Examples/SPM/Sources/SPMIntegration/main.swift: -------------------------------------------------------------------------------- 1 | import Ably 2 | -------------------------------------------------------------------------------- /MAINTAINERS.md: -------------------------------------------------------------------------------- 1 | This repository is owned by the Ably SDK team. 2 | -------------------------------------------------------------------------------- /Examples/AblyCarthage/Cartfile: -------------------------------------------------------------------------------- 1 | git "../../../ably-cocoa" "HEAD" 2 | 3 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTSRWebSocket.h: -------------------------------------------------------------------------------- 1 | ../../SocketRocket/ARTSRWebSocket.h -------------------------------------------------------------------------------- /Cartfile: -------------------------------------------------------------------------------- 1 | github "ably/delta-codec-cocoa" == 1.3.3 2 | github "rvi/msgpack-objective-C" == 0.4.0 3 | -------------------------------------------------------------------------------- /images/CocoaSDK-github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ably/ably-cocoa/HEAD/images/CocoaSDK-github.png -------------------------------------------------------------------------------- /Cartfile.resolved: -------------------------------------------------------------------------------- 1 | github "ably/delta-codec-cocoa" "1.3.3" 2 | github "rvi/msgpack-objective-C" "0.4.0" 3 | -------------------------------------------------------------------------------- /fastlane/Pluginfile: -------------------------------------------------------------------------------- 1 | # Autogenerated by fastlane 2 | # 3 | # Ensure this file is checked in to source control! 4 | -------------------------------------------------------------------------------- /Scripts/version-constants.sh: -------------------------------------------------------------------------------- 1 | VERSION_CONFIG_VAR="CURRENT_PROJECT_VERSION" 2 | VERSION_CONFIG_FILE="Version.xcconfig" 3 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "ably-common"] 2 | path = Test/AblyTests/ably-common 3 | url = https://github.com/ably/ably-common.git 4 | -------------------------------------------------------------------------------- /Ably-SoakTest-App/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Test/AblyTestingObjC/include/AblyTestingObjC.h: -------------------------------------------------------------------------------- 1 | #import "../Dependencies/steipete/Aspects.h" 2 | #import "../Test Utilities/NSObject+TestSuite.h" 3 | -------------------------------------------------------------------------------- /Examples/AblyCarthage/AblyCarthage/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Examples/AblyPush/AblyPushExample/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTOSReachability.h: -------------------------------------------------------------------------------- 1 | #import "ARTReachability.h" 2 | 3 | @interface ARTOSReachability : NSObject 4 | @end 5 | -------------------------------------------------------------------------------- /Examples/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | /.build 3 | /Packages 4 | /*.xcodeproj 5 | xcuserdata/ 6 | DerivedData/ 7 | .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata 8 | -------------------------------------------------------------------------------- /Examples/AblyPush/AblyPushExample/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Examples/SPM/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | /.build 3 | /Packages 4 | /*.xcodeproj 5 | xcuserdata/ 6 | DerivedData/ 7 | .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata 8 | -------------------------------------------------------------------------------- /Examples/Tests/Podfile: -------------------------------------------------------------------------------- 1 | platform :ios, '10.0' 2 | use_frameworks! 3 | 4 | pod 'Ably', :path => '../..' 5 | 6 | target 'Tests' do 7 | 8 | end 9 | 10 | target 'TestsTests' do 11 | 12 | end 13 | 14 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTJsonEncoder.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #import "ARTJsonLikeEncoder.h" 4 | 5 | @interface ARTJsonEncoder : NSObject 6 | 7 | @end 8 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTMsgPackEncoder.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #import "ARTJsonLikeEncoder.h" 4 | 5 | @interface ARTMsgPackEncoder : NSObject 6 | 7 | @end 8 | -------------------------------------------------------------------------------- /Ably.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Scripts/get-version.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | source "$(dirname "$0")/version-constants.sh" 4 | 5 | prefix="$VERSION_CONFIG_VAR = " 6 | version_config=$(cat $VERSION_CONFIG_FILE) 7 | echo ${version_config:${#prefix}} 8 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTNSArray+ARTFunctional.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface NSArray (ARTFunctional) 4 | 5 | - (NSArray *)artMap:(id(^)(id))f; 6 | - (NSArray *)artFilter:(BOOL(^)(id))f; 7 | 8 | @end 9 | -------------------------------------------------------------------------------- /Examples/AblyPush/AblyPushExample/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Examples/AblyPush/AblyPushExample/InfoLP.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTChannelOptions+Private.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface ARTChannelOptions () 5 | 6 | @property (nonatomic, getter=isFrozen) BOOL frozen; 7 | 8 | @end 9 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTHttp+Private.h: -------------------------------------------------------------------------------- 1 | #import "ARTHttp.h" 2 | 3 | NS_ASSUME_NONNULL_BEGIN 4 | 5 | @interface ARTHttp (Private) 6 | 7 | @property (readonly) dispatch_queue_t queue; 8 | 9 | @end 10 | 11 | NS_ASSUME_NONNULL_END 12 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTAuthOptions+Private.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | NS_ASSUME_NONNULL_BEGIN 4 | 5 | @interface ARTAuthOptions () 6 | 7 | - (instancetype)initDefaults; 8 | 9 | @end 10 | 11 | NS_ASSUME_NONNULL_END 12 | -------------------------------------------------------------------------------- /Examples/AblyPush/AblyPushExample/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Examples/AblyCarthage/AblyCarthage/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTConstants.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | extern NSString *const ARTHttpHeaderFieldErrorCodeKey; 4 | extern NSString *const ARTHttpHeaderFieldErrorMessageKey; 5 | extern NSUInteger const ARTIdempotentLibraryGeneratedIdLength; 6 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTTokenParams+Private.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface ARTTokenParams (Private) 4 | 5 | - (ARTTokenRequest *)sign:(NSString *)key; 6 | - (ARTTokenRequest *)sign:(NSString *)key withNonce:(NSString *)nonce; 7 | 8 | @end 9 | -------------------------------------------------------------------------------- /Source/ARTConstants.m: -------------------------------------------------------------------------------- 1 | #import "ARTConstants.h" 2 | 3 | NSString *const ARTHttpHeaderFieldErrorCodeKey = @"x-ably-errorcode"; 4 | NSString *const ARTHttpHeaderFieldErrorMessageKey = @"x-ably-errormessage"; 5 | NSUInteger const ARTIdempotentLibraryGeneratedIdLength = 9; // bytes 6 | -------------------------------------------------------------------------------- /Test/AblyTests/Test Utilities/MockErrorChecker.swift: -------------------------------------------------------------------------------- 1 | import Ably.Private 2 | 3 | class MockErrorChecker: ErrorChecker { 4 | var isTokenError: Bool! 5 | 6 | func isTokenError(_ errorInfo: ARTErrorInfo) -> Bool { 7 | return isTokenError 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Source/ARTPresence.m: -------------------------------------------------------------------------------- 1 | #import "ARTPresence.h" 2 | 3 | @implementation ARTPresence 4 | 5 | - (void)history:(ARTPaginatedPresenceCallback)callback { 6 | NSAssert(false, @"-[%@ %@] should always be overriden.", self.class, NSStringFromSelector(_cmd)); 7 | } 8 | 9 | @end 10 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTNSHTTPURLResponse+ARTPaginated.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | NS_ASSUME_NONNULL_BEGIN 4 | 5 | @interface NSHTTPURLResponse (ARTPaginated) 6 | 7 | - (nullable NSDictionary *)extractLinks; 8 | 9 | @end 10 | 11 | NS_ASSUME_NONNULL_END 12 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTNSURL+ARTUtils.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | NS_ASSUME_NONNULL_BEGIN 4 | 5 | @interface NSURL (ARTUtils) 6 | 7 | + (nullable NSURL *)copyFromURL:(NSURL *)url withHost:(NSString *)host; 8 | 9 | @end 10 | 11 | NS_ASSUME_NONNULL_END 12 | -------------------------------------------------------------------------------- /Examples/AblyCarthage/AblyCarthage/ViewController.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Ably 3 | 4 | class ViewController: UIViewController { 5 | 6 | override func viewDidLoad() { 7 | super.viewDidLoad() 8 | // Do any additional setup after loading the view. 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Examples/AblyPush/AblyPushExample/Assets.xcassets/push-enabled.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "push-enabled.pdf", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Examples/AblyPush/AblyPushExample/Assets.xcassets/push-disabled.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "push-disabled.pdf", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /.github/workflows/features.yml: -------------------------------------------------------------------------------- 1 | name: Features 2 | 3 | on: 4 | pull_request: 5 | push: 6 | branches: 7 | - main 8 | 9 | jobs: 10 | build: 11 | uses: ably/features/.github/workflows/sdk-features.yml@main 12 | with: 13 | repository-name: ably-cocoa 14 | secrets: inherit 15 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTInternalLog+Testing.h: -------------------------------------------------------------------------------- 1 | @import Foundation; 2 | 3 | @protocol ARTInternalLogCore; 4 | 5 | NS_ASSUME_NONNULL_BEGIN 6 | 7 | @interface ARTInternalLog () 8 | 9 | @property (nonatomic, readonly) id core; 10 | 11 | @end 12 | 13 | NS_ASSUME_NONNULL_END 14 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTMessageOperation+Private.h: -------------------------------------------------------------------------------- 1 | @import Foundation; 2 | #import 3 | #import "ARTDictionarySerializable.h" 4 | 5 | NS_ASSUME_NONNULL_BEGIN 6 | 7 | @interface ARTMessageOperation () 8 | @end 9 | 10 | NS_ASSUME_NONNULL_END 11 | -------------------------------------------------------------------------------- /Source/ARTJitterCoefficientGenerator.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import "ARTJitterCoefficientGenerator.h" 3 | 4 | @implementation ARTDefaultJitterCoefficientGenerator 5 | 6 | - (double)generateJitterCoefficient { 7 | return 0.8 + 0.2 * ((double)arc4random() / UINT32_MAX); 8 | } 9 | 10 | @end 11 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTNSString+ARTUtil.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #define NSStringFromBOOL(aBOOL) ((aBOOL) ? @"YES" : @"NO") 4 | 5 | @interface NSString (ARTUtil) 6 | 7 | + (NSString *)nilToEmpty:(NSString*)aString; 8 | - (BOOL)isEmptyString; 9 | - (BOOL)isNotEmptyString; 10 | 11 | @end 12 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTQueuedDealloc.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | NS_ASSUME_NONNULL_BEGIN 4 | 5 | @interface ARTQueuedDealloc : NSObject 6 | 7 | - (instancetype)init NS_UNAVAILABLE; 8 | - (instancetype)init:(id)ref queue:(dispatch_queue_t)queue; 9 | 10 | @end 11 | 12 | NS_ASSUME_NONNULL_END 13 | -------------------------------------------------------------------------------- /fastlane/Scanfile: -------------------------------------------------------------------------------- 1 | open_report false 2 | clean true 3 | skip_slack true 4 | ensure_devices_found true 5 | output_types "junit" 6 | # I'm being explicit about this because I want to make sure it's being used, to make sure that trainer is used to generate the JUnit report 7 | xcodebuild_formatter "xcbeautify" 8 | result_bundle true 9 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | # Autogenerated by fastlane 2 | # 3 | # Ensure this file is checked in to source control! 4 | 5 | source "https://rubygems.org" 6 | 7 | gem 'jazzy' 8 | 9 | gem 'fastlane' 10 | 11 | plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile') 12 | eval_gemfile(plugins_path) if File.exist?(plugins_path) 13 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTNSDate+ARTUtil.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface NSDate (ARTUtil) 4 | 5 | + (instancetype)artDateFromNumberMs:(NSNumber *)number; 6 | + (instancetype)artDateFromIntegerMs:(long long)ms; 7 | 8 | - (NSNumber *)artToNumberMs; 9 | - (NSInteger)artToIntegerMs; 10 | 11 | @end 12 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTFallbackHosts.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @class ARTClientOptions; 4 | 5 | NS_ASSUME_NONNULL_BEGIN 6 | 7 | @interface ARTFallbackHosts : NSObject 8 | 9 | + (nullable NSArray *)hostsFromOptions:(ARTClientOptions *)options; 10 | 11 | @end 12 | 13 | NS_ASSUME_NONNULL_END 14 | -------------------------------------------------------------------------------- /Test/AblyTests/Tests/ARTDefaultTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | import Ably.ARTDefault // System under Test 4 | 5 | class ARTDefaultTests: XCTestCase { 6 | 7 | func testVersions() { 8 | XCTAssertEqual(ARTDefault.apiVersion(), "4") 9 | XCTAssertEqual(ARTDefault.libraryVersion(), "1.2.55") 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTStringifiable+Private.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface ARTStringifiable() 4 | 5 | - (nonnull instancetype)initWithString:(nonnull NSString *)value; 6 | - (nonnull instancetype)initWithNumber:(nonnull NSNumber *)value; 7 | - (nonnull instancetype)initWithBool:(BOOL)value; 8 | 9 | @end 10 | -------------------------------------------------------------------------------- /Source/ARTNSMutableDictionary+ARTDictionaryUtil.m: -------------------------------------------------------------------------------- 1 | #import "ARTNSMutableDictionary+ARTDictionaryUtil.h" 2 | 3 | @implementation NSMutableDictionary (ARTDictionaryUtil) 4 | 5 | - (void)addValueAsURLQueryItem:(NSString *)value forKey:(NSString *)key { 6 | self[key] = [NSURLQueryItem queryItemWithName:key value:value]; 7 | } 8 | 9 | @end 10 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTFallback+Private.h: -------------------------------------------------------------------------------- 1 | #import "ARTFallback.h" 2 | 3 | NS_ASSUME_NONNULL_BEGIN 4 | 5 | extern void (^const ARTFallback_shuffleArray)(NSMutableArray *); 6 | 7 | @interface ARTFallback () 8 | 9 | @property (readwrite, nonatomic) NSMutableArray *hosts; 10 | 11 | @end 12 | 13 | NS_ASSUME_NONNULL_END 14 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTNSMutableURLRequest+ARTPaginated.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | NS_ASSUME_NONNULL_BEGIN 4 | 5 | @interface NSMutableURLRequest (ARTPaginated) 6 | 7 | + (nullable NSMutableURLRequest *)requestWithPath:(NSString *)path relativeTo:(NSURLRequest *)request; 8 | 9 | @end 10 | 11 | NS_ASSUME_NONNULL_END 12 | -------------------------------------------------------------------------------- /Examples/AblyPush/AblyPushExample/Buttons/VerticalLabelStyle.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct VerticalLabelStyle: LabelStyle { 4 | func makeBody(configuration: Configuration) -> some View { 5 | VStack(alignment: .center, spacing: 8) { 6 | configuration.icon 7 | configuration.title 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Source/ARTWrapperSDKProxyOptions.m: -------------------------------------------------------------------------------- 1 | #import "ARTWrapperSDKProxyOptions.h" 2 | 3 | @implementation ARTWrapperSDKProxyOptions 4 | 5 | - (instancetype)initWithAgents:(nullable NSDictionary *)agents { 6 | if (self = [super init]) { 7 | _agents = [agents copy]; 8 | } 9 | 10 | return self; 11 | } 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTURLSessionServerTrust.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #import 4 | #import "ARTURLSession.h" 5 | 6 | NS_ASSUME_NONNULL_BEGIN 7 | 8 | @interface ARTURLSessionServerTrust : NSObject 9 | 10 | @end 11 | 12 | NS_ASSUME_NONNULL_END 13 | -------------------------------------------------------------------------------- /Examples/SPM/Tests/SPMTests/SPMTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import Ably 3 | 4 | final class SPMTests: XCTestCase { 5 | func ablyInitTest() { 6 | let clientOptions = ARTClientOptions() 7 | let _ = ARTRest(options: clientOptions) 8 | let _ = ARTRealtime(options: clientOptions) 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Source/ARTPendingMessage.m: -------------------------------------------------------------------------------- 1 | #import "ARTPendingMessage.h" 2 | 3 | @implementation ARTPendingMessage 4 | 5 | - (instancetype)initWithProtocolMessage:(ARTProtocolMessage *)msg ackCallback:(nullable ARTStatusCallback)ackCallback { 6 | self = [super initWithProtocolMessage:msg sentCallback:nil ackCallback:ackCallback]; 7 | return self; 8 | } 9 | 10 | @end 11 | -------------------------------------------------------------------------------- /Source/ARTWebSocketFactory.m: -------------------------------------------------------------------------------- 1 | #import "ARTWebSocketFactory.h" 2 | #import "ARTSRWebSocket.h" 3 | 4 | @implementation ARTDefaultWebSocketFactory 5 | 6 | - (id)createWebSocketWithURLRequest:(NSURLRequest *)request logger:(ARTInternalLog *)logger { 7 | return [[ARTSRWebSocket alloc] initWithURLRequest:request logger:logger]; 8 | } 9 | 10 | @end 11 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTFormEncode.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | NS_ASSUME_NONNULL_BEGIN 4 | 5 | /** 6 | Express the input dictionary as a `application/x-www-form-urlencoded` string. 7 | If the parameters dictionary is nil or empty, returns nil. 8 | */ 9 | NSString *ARTFormEncode(NSDictionary *parameters); 10 | 11 | NS_ASSUME_NONNULL_END 12 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTNSError+ARTUtils.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | NS_ASSUME_NONNULL_BEGIN 4 | 5 | @interface NSError (ARTUtils) 6 | 7 | @property (nullable, readonly) NSString *requestId; 8 | 9 | + (NSError *)copyFromError:(NSError *)error withRequestId:(nullable NSString *)requestId; 10 | 11 | @end 12 | 13 | NS_ASSUME_NONNULL_END 14 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/NSURLQueryItem+Stringifiable.h: -------------------------------------------------------------------------------- 1 | #import 2 | @class ARTStringifiable; 3 | 4 | NS_ASSUME_NONNULL_BEGIN 5 | 6 | @interface NSURLQueryItem (ARTNSURLQueryItem_Stringifiable) 7 | 8 | + (NSURLQueryItem*)itemWithName:(NSString *)name value:(ARTStringifiable *)value; 9 | 10 | @end 11 | 12 | NS_ASSUME_NONNULL_END 13 | -------------------------------------------------------------------------------- /Ably.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTErrorInfo+Private.h: -------------------------------------------------------------------------------- 1 | @import Foundation; 2 | #import 3 | 4 | #ifdef ABLY_SUPPORTS_PLUGINS 5 | @import _AblyPluginSupportPrivate; 6 | #endif 7 | 8 | NS_ASSUME_NONNULL_BEGIN 9 | 10 | #ifdef ABLY_SUPPORTS_PLUGINS 11 | @interface ARTErrorInfo () 12 | @end 13 | #endif 14 | 15 | NS_ASSUME_NONNULL_END 16 | -------------------------------------------------------------------------------- /Source/ARTNSURL+ARTUtils.m: -------------------------------------------------------------------------------- 1 | #import "ARTNSURL+ARTUtils.h" 2 | 3 | @implementation NSURL (ARTUtils) 4 | 5 | + (NSURL *)copyFromURL:(NSURL *)url withHost:(NSString *)host { 6 | NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:YES]; 7 | components.host = host; 8 | 9 | return components.URL; 10 | } 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /Source/NSURLQueryItem+Stringifiable.m: -------------------------------------------------------------------------------- 1 | #import "NSURLQueryItem+Stringifiable.h" 2 | #import "ARTStringifiable.h" 3 | 4 | @implementation NSURLQueryItem (ARTNSURLQueryItem_Stringifiable) 5 | 6 | + (NSURLQueryItem *)itemWithName:(NSString *)name value:(ARTStringifiable *)value { 7 | return [NSURLQueryItem queryItemWithName:name value:[value stringValue]]; 8 | } 9 | 10 | @end 11 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTNSMutableRequest+ARTRest.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @protocol ARTEncoder; 4 | 5 | NS_ASSUME_NONNULL_BEGIN 6 | 7 | @interface NSMutableURLRequest (ARTRest) 8 | 9 | - (void)setAcceptHeader:(id)defaultEncoder encoders:(NSDictionary> *)encoders; 10 | 11 | @end 12 | 13 | NS_ASSUME_NONNULL_END 14 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTDefault+Private.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | extern NSString *const ARTDefaultProduction; 4 | 5 | @interface ARTDefault (Private) 6 | 7 | + (void)setConnectionStateTtl:(NSTimeInterval)value; 8 | + (void)setMaxMessageSize:(NSInteger)value; 9 | 10 | + (NSInteger)maxSandboxMessageSize; 11 | + (NSInteger)maxProductionMessageSize; 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTPaginatedResult+Subclass.h: -------------------------------------------------------------------------------- 1 | @import Foundation; 2 | #import 3 | 4 | NS_ASSUME_NONNULL_BEGIN 5 | 6 | @interface ARTPaginatedResult () 7 | 8 | @property (nullable, nonatomic, readonly) NSStringDictionary *wrapperSDKAgents; 9 | @property (nonatomic, readonly) ARTInternalLog *logger; 10 | 11 | @end 12 | 13 | NS_ASSUME_NONNULL_END 14 | -------------------------------------------------------------------------------- /Source/include/Ably/ARTPresence.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #import 4 | #import 5 | #import 6 | 7 | NS_ASSUME_NONNULL_BEGIN 8 | 9 | /// :nodoc: 10 | @interface ARTPresence : NSObject 11 | 12 | - (void)history:(ARTPaginatedPresenceCallback)callback; 13 | 14 | @end 15 | 16 | NS_ASSUME_NONNULL_END 17 | -------------------------------------------------------------------------------- /Source/ARTErrorChecker.m: -------------------------------------------------------------------------------- 1 | #import "ARTErrorChecker.h" 2 | #import "ARTTypes.h" 3 | #import "ARTStatus.h" 4 | 5 | @implementation ARTDefaultErrorChecker 6 | 7 | - (BOOL)isTokenError:(ARTErrorInfo *)errorInfo { 8 | // RTH15h1 9 | return errorInfo.statusCode == 401 && errorInfo.code >= ARTErrorTokenErrorUnspecified && errorInfo.code < ARTErrorConnectionLimitsExceeded; 10 | } 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTNSMutableDictionary+ARTDictionaryUtil.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | NS_ASSUME_NONNULL_BEGIN 4 | 5 | @interface NSMutableDictionary (ARTDictionaryUtil) 6 | 7 | /** 8 | Creates NSURLQueryItem for given value, and key. 9 | */ 10 | - (void)addValueAsURLQueryItem:(NSString *)value forKey:(NSString *)key; 11 | 12 | @end 13 | 14 | NS_ASSUME_NONNULL_END 15 | -------------------------------------------------------------------------------- /Examples/AblyPush/AblyLocationPush/AblyLocationPush.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.application-groups 6 | 7 | group.$(CFBundleIdentifier) 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Scripts/log-environment-information.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Prints the public IP address of the host machine, and the result of resolving sandbox-realtime.ably.io. Useful information to have in a CI environment. 4 | 5 | set -e 6 | 7 | ip=$(curl -s https://api.ipify.org) 8 | echo "Public IP address is: $ip" 9 | 10 | echo "Output of \`dig sandbox-realtime.ably.io\`:" 11 | dig sandbox-realtime.ably.io 12 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTPresence+Private.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import "ARTChannel.h" 3 | 4 | @interface ARTPresenceQuery () 5 | 6 | - (NSMutableArray *)asQueryItems; 7 | 8 | @end 9 | 10 | @interface ARTPresence () 11 | 12 | @property (readonly, getter=getChannel) ARTChannel *channel; 13 | 14 | - (instancetype)initWithChannel:(ARTChannel *)channel; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Source/include/Ably/Ably.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | /** 4 | * :nodoc: 5 | * Project version number for ably-ios. 6 | */ 7 | FOUNDATION_EXPORT double ablyVersionNumber; 8 | 9 | /** 10 | * :nodoc: 11 | * Project version string for ably-ios. 12 | */ 13 | FOUNDATION_EXPORT const unsigned char ablyVersionString[]; 14 | 15 | #import 16 | #import 17 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTInternalLogCore+Testing.h: -------------------------------------------------------------------------------- 1 | @import Foundation; 2 | #import "ARTInternalLog.h" 3 | 4 | NS_ASSUME_NONNULL_BEGIN 5 | 6 | @interface ARTDefaultInternalLogCore () 7 | 8 | // Exposed to test suite so that it can make assertions about how the convenience initializers populate it. 9 | @property (nonatomic, readonly) id logger; 10 | 11 | @end 12 | 13 | NS_ASSUME_NONNULL_END 14 | -------------------------------------------------------------------------------- /Scripts/jazzy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Generates Jazzy documentation: https://github.com/realm/jazzy 4 | 5 | bundle exec jazzy \ 6 | --objc \ 7 | --clean \ 8 | --author Ably \ 9 | --module-version 1.2.55 \ 10 | --umbrella-header Source/include/Ably/AblyPublic.h \ 11 | --framework-root Source \ 12 | --module Ably \ 13 | --sdk iphonesimulator \ 14 | --readme Docs/Main.md \ 15 | --output Docs/jazzy 16 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTReachability.h: -------------------------------------------------------------------------------- 1 | @import Foundation; 2 | 3 | @class ARTInternalLog; 4 | 5 | NS_ASSUME_NONNULL_BEGIN 6 | 7 | @protocol ARTReachability 8 | 9 | - (instancetype)initWithLogger:(ARTInternalLog *)logger queue:(dispatch_queue_t)queue; 10 | 11 | - (void)listenForHost:(NSString *)host callback:(void (^)(BOOL))callback; 12 | - (void)off; 13 | 14 | @end 15 | 16 | NS_ASSUME_NONNULL_END 17 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTWrapperSDKProxyPush+Private.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @class ARTWrapperSDKProxyOptions; 4 | 5 | NS_ASSUME_NONNULL_BEGIN 6 | 7 | @interface ARTWrapperSDKProxyPush () 8 | 9 | - (instancetype)initWithPush:(ARTPush *)push 10 | proxyOptions:(ARTWrapperSDKProxyOptions *)proxyOptions NS_DESIGNATED_INITIALIZER; 11 | 12 | @end 13 | 14 | NS_ASSUME_NONNULL_END 15 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTDeviceIdentityTokenDetails+Private.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | NS_ASSUME_NONNULL_BEGIN 4 | 5 | @interface ARTDeviceIdentityTokenDetails () 6 | 7 | - (NSData *)archiveWithLogger:(nullable ARTInternalLog *)logger; 8 | 9 | + (nullable ARTDeviceIdentityTokenDetails *)unarchive:(NSData *)data withLogger:(nullable ARTInternalLog *)logger; 10 | 11 | @end 12 | 13 | NS_ASSUME_NONNULL_END 14 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTLocalDeviceStorage.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import "ARTDeviceStorage.h" 3 | 4 | @class ARTInternalLog; 5 | 6 | NS_ASSUME_NONNULL_BEGIN 7 | 8 | /// :nodoc: 9 | @interface ARTLocalDeviceStorage : NSObject 10 | 11 | - (instancetype)initWithLogger:(ARTInternalLog *)logger; 12 | 13 | + (instancetype)newWithLogger:(ARTInternalLog *)logger; 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTLogAdapter+Testing.h: -------------------------------------------------------------------------------- 1 | @import Foundation; 2 | #import "ARTLogAdapter.h" 3 | 4 | NS_ASSUME_NONNULL_BEGIN 5 | 6 | @interface ARTLogAdapter () 7 | 8 | // Exposed to test suite so that the ARTDefaultInternalLogCore tests can make assertions about how that class's convenience intializers initialize an ARTLogAdapter object. 9 | @property (nonatomic, readonly) ARTLog *logger; 10 | 11 | @end 12 | 13 | NS_ASSUME_NONNULL_END 14 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTWrapperSDKProxyRealtime+Private.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @class ARTWrapperSDKProxyOptions; 4 | 5 | NS_ASSUME_NONNULL_BEGIN 6 | 7 | @interface ARTWrapperSDKProxyRealtime () 8 | 9 | - (instancetype)initWithRealtime:(ARTRealtime *)realtime 10 | proxyOptions:(ARTWrapperSDKProxyOptions *)proxyOptions NS_DESIGNATED_INITIALIZER; 11 | 12 | @end 13 | 14 | NS_ASSUME_NONNULL_END 15 | -------------------------------------------------------------------------------- /Ably-SoakTest-App/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // Ably-SoakTest-App2 4 | // 5 | // Created by Toni Cárdenas on 26/11/2019. 6 | // Copyright © 2019 Ably. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ViewController: UIViewController { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | // Do any additional setup after loading the view. 16 | } 17 | 18 | 19 | } 20 | 21 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTWrapperSDKProxyPushAdmin+Private.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @class ARTWrapperSDKProxyOptions; 4 | 5 | NS_ASSUME_NONNULL_BEGIN 6 | 7 | @interface ARTWrapperSDKProxyPushAdmin () 8 | 9 | - (instancetype)initWithPushAdmin:(ARTPushAdmin *)pushAdmin 10 | proxyOptions:(ARTWrapperSDKProxyOptions *)proxyOptions NS_DESIGNATED_INITIALIZER; 11 | 12 | @end 13 | 14 | NS_ASSUME_NONNULL_END 15 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTURLSession.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | NS_ASSUME_NONNULL_BEGIN 4 | 5 | @protocol ARTURLSession 6 | 7 | @property (readonly) dispatch_queue_t queue; 8 | 9 | - (instancetype)init:(dispatch_queue_t)queue; 10 | 11 | - (NSObject *)get:(NSURLRequest *)request completion:(ARTURLRequestCallback)callback; 12 | 13 | - (void)finishTasksAndInvalidate; 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTWrapperSDKProxyPushChannel+Private.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @class ARTWrapperSDKProxyOptions; 4 | 5 | NS_ASSUME_NONNULL_BEGIN 6 | 7 | @interface ARTWrapperSDKProxyPushChannel () 8 | 9 | - (instancetype)initWithPushChannel:(ARTPushChannel *)pushChannel 10 | proxyOptions:(ARTWrapperSDKProxyOptions *)proxyOptions NS_DESIGNATED_INITIALIZER; 11 | 12 | @end 13 | 14 | NS_ASSUME_NONNULL_END 15 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTWrapperSDKProxyRealtimeChannel+Private.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @class ARTWrapperSDKProxyOptions; 4 | 5 | NS_ASSUME_NONNULL_BEGIN 6 | 7 | @interface ARTWrapperSDKProxyRealtimeChannel () 8 | 9 | - (instancetype)initWithChannel:(ARTRealtimeChannel *)channel 10 | proxyOptions:(ARTWrapperSDKProxyOptions *)proxyOptions NS_DESIGNATED_INITIALIZER; 11 | 12 | @end 13 | 14 | NS_ASSUME_NONNULL_END 15 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTDevicePushDetails+Private.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @class ARTErrorInfo; 4 | 5 | NS_ASSUME_NONNULL_BEGIN 6 | 7 | @interface ARTDevicePushDetails () 8 | 9 | @property (nonatomic, readwrite) NSMutableDictionary *recipient; 10 | @property (nullable, nonatomic, readwrite) NSString *state; 11 | @property (nullable, nonatomic, readwrite) ARTErrorInfo *errorReason; 12 | 13 | @end 14 | 15 | NS_ASSUME_NONNULL_END 16 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTWrapperSDKProxyRealtimeChannels+Private.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @class ARTWrapperSDKProxyOptions; 4 | 5 | NS_ASSUME_NONNULL_BEGIN 6 | 7 | @interface ARTWrapperSDKProxyRealtimeChannels () 8 | 9 | - (instancetype)initWithChannels:(ARTRealtimeChannels *)channels 10 | proxyOptions:(ARTWrapperSDKProxyOptions *)proxyOptions NS_DESIGNATED_INITIALIZER; 11 | 12 | @end 13 | 14 | NS_ASSUME_NONNULL_END 15 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTDataQuery+Private.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import "ARTRealtimeChannel+Private.h" 3 | 4 | NS_ASSUME_NONNULL_BEGIN 5 | 6 | @interface ARTDataQuery (Private) 7 | 8 | - (nullable NSMutableArray /* */ *)asQueryItems:(NSError *_Nullable *)error; 9 | 10 | @end 11 | 12 | @interface ARTRealtimeHistoryQuery () 13 | 14 | @property (readwrite) ARTRealtimeChannelInternal *realtimeChannel; 15 | 16 | @end 17 | 18 | NS_ASSUME_NONNULL_END 19 | -------------------------------------------------------------------------------- /Source/include/Ably/ARTAuthDetails.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | NS_ASSUME_NONNULL_BEGIN 4 | 5 | /** 6 | * Contains the token string used to authenticate a client with Ably. 7 | */ 8 | @interface ARTAuthDetails : NSObject 9 | 10 | /** 11 | * The authentication token string. 12 | */ 13 | @property (nonatomic, copy) NSString *accessToken; 14 | 15 | /// :nodoc: 16 | - (instancetype)initWithToken:(NSString *)token; 17 | 18 | @end 19 | 20 | NS_ASSUME_NONNULL_END 21 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTWrapperSDKProxyRealtimePresence+Private.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @class ARTWrapperSDKProxyOptions; 4 | 5 | NS_ASSUME_NONNULL_BEGIN 6 | 7 | @interface ARTWrapperSDKProxyRealtimePresence () 8 | 9 | - (instancetype)initWithRealtimePresence:(ARTRealtimePresence *)realtimePresence 10 | proxyOptions:(ARTWrapperSDKProxyOptions *)proxyOptions NS_DESIGNATED_INITIALIZER; 11 | 12 | @end 13 | 14 | NS_ASSUME_NONNULL_END 15 | -------------------------------------------------------------------------------- /Examples/AblyPush/AblyLocationPush/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSExtension 6 | 7 | NSExtensionPointIdentifier 8 | com.apple.location.push.service 9 | NSExtensionPrincipalClass 10 | $(PRODUCT_MODULE_NAME).LocationPushService 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /Source/include/Ably/ARTStringifiable.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | NS_ASSUME_NONNULL_BEGIN 4 | 5 | 6 | /// :nodoc: 7 | @interface ARTStringifiable : NSObject 8 | 9 | - (instancetype)init UNAVAILABLE_ATTRIBUTE; 10 | 11 | @property(nonnull, nonatomic, readonly) NSString* stringValue; 12 | 13 | + (ARTStringifiable*)withString:(NSString *)value; 14 | + (ARTStringifiable*)withNumber:(NSNumber *)value; 15 | + (ARTStringifiable*)withBool:(BOOL)value; 16 | 17 | @end 18 | 19 | NS_ASSUME_NONNULL_END 20 | -------------------------------------------------------------------------------- /Test/AblyTests/Test Utilities/MockVersion2Log.swift: -------------------------------------------------------------------------------- 1 | import Ably.Private 2 | 3 | class MockVersion2Log: NSObject, Version2Log { 4 | var logLevel: ARTLogLevel = .none 5 | 6 | var lastReceivedLogMessageArguments: (message: String, level: ARTLogLevel, fileName: String, line: Int)? 7 | 8 | func log(_ message: String, with level: ARTLogLevel, file fileName: String, line: Int) { 9 | lastReceivedLogMessageArguments = (message: message, level: level, fileName: fileName, line: line) 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTMessageVersion+Private.h: -------------------------------------------------------------------------------- 1 | @import Foundation; 2 | #import 3 | 4 | NS_ASSUME_NONNULL_BEGIN 5 | 6 | @interface ARTMessageVersion () 7 | 8 | // Serialize the MessageVersion object 9 | - (void)writeToDictionary:(NSMutableDictionary *)dictionary; 10 | 11 | // Deserialize a MessageVersion object from a NSDictionary object 12 | + (instancetype)createFromDictionary:(NSDictionary *)jsonObject; 13 | 14 | @end 15 | 16 | NS_ASSUME_NONNULL_END 17 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTPublicRealtimeChannelUnderlyingObjects.h: -------------------------------------------------------------------------------- 1 | #ifdef ABLY_SUPPORTS_PLUGINS 2 | 3 | @import Foundation; 4 | @import _AblyPluginSupportPrivate; 5 | 6 | NS_ASSUME_NONNULL_BEGIN 7 | 8 | @interface APDefaultPublicRealtimeChannelUnderlyingObjects: NSObject 9 | 10 | - (instancetype)initWithClient:(id)client 11 | channel:(id)channel; 12 | 13 | @end 14 | 15 | NS_ASSUME_NONNULL_END 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTWrapperSDKProxyRealtimeAnnotations+Private.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @class ARTWrapperSDKProxyOptions; 4 | 5 | NS_ASSUME_NONNULL_BEGIN 6 | 7 | @interface ARTWrapperSDKProxyRealtimeAnnotations () 8 | 9 | - (instancetype)initWithRealtimeAnnotations:(ARTRealtimeAnnotations *)realtimeAnnotations 10 | proxyOptions:(ARTWrapperSDKProxyOptions *)proxyOptions NS_DESIGNATED_INITIALIZER; 11 | 12 | @end 13 | 14 | NS_ASSUME_NONNULL_END 15 | -------------------------------------------------------------------------------- /Source/ARTNSString+ARTUtil.m: -------------------------------------------------------------------------------- 1 | #import "ARTNSString+ARTUtil.h" 2 | 3 | @implementation NSString (ARTUtil) 4 | 5 | + (NSString *)nilToEmpty:(NSString*)aString { 6 | if ([aString length] == 0) { 7 | return @""; 8 | } 9 | return aString; 10 | } 11 | 12 | - (BOOL)isEmptyString { 13 | return [[self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] isEqualToString:@""]; 14 | } 15 | 16 | - (BOOL)isNotEmptyString { 17 | return ![self isEmptyString]; 18 | } 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTMessageAnnotations+Private.h: -------------------------------------------------------------------------------- 1 | @import Foundation; 2 | #import 3 | 4 | NS_ASSUME_NONNULL_BEGIN 5 | 6 | @interface ARTMessageAnnotations () 7 | 8 | // Serialize the MessageAnnotations object 9 | - (void)writeToDictionary:(NSMutableDictionary *)dictionary; 10 | 11 | // Deserialize a MessageAnnotations object from a NSDictionary object 12 | + (instancetype)createFromDictionary:(NSDictionary *)jsonObject; 13 | 14 | @end 15 | 16 | NS_ASSUME_NONNULL_END 17 | -------------------------------------------------------------------------------- /Examples/AblyPush/AblyPushExample/AblyPushExample.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | aps-environment 6 | development 7 | com.apple.developer.location.push 8 | 9 | com.apple.security.application-groups 10 | 11 | group.$(CFBundleIdentifier).AblyLocationPush 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Source/ARTQueuedDealloc.m: -------------------------------------------------------------------------------- 1 | #import "ARTQueuedDealloc.h" 2 | #import "ARTGCD.h" 3 | 4 | @implementation ARTQueuedDealloc { 5 | id _ref; 6 | dispatch_queue_t _queue; 7 | } 8 | 9 | - (instancetype)init:(id)ref queue:(dispatch_queue_t)queue { 10 | self = [super init]; 11 | if (self) { 12 | _ref = ref; 13 | _queue = queue; 14 | } 15 | return self; 16 | } 17 | 18 | - (void)dealloc { 19 | __block id ref = _ref; 20 | art_dispatch_async(_queue, ^{ 21 | ref = nil; 22 | }); 23 | } 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /Test/AblyTests/Test Utilities/NSObject+TestSuite.swift: -------------------------------------------------------------------------------- 1 | import AblyTestingObjC 2 | 3 | extension NSObject { 4 | 5 | /// Inject a block of code to the identified class method. 6 | class func testSuite_injectIntoClassMethod(_ selector: Selector, code: @escaping ()->()) -> AspectToken? { 7 | let block: @convention(block) (AspectInfo) -> Void = { _ in 8 | code() 9 | } 10 | return try? self.aspect_hook(selector, with: AspectOptions(), usingBlock: unsafeBitCast(block, to: AnyObject.self)) 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTWrapperSDKProxyPushDeviceRegistrations+Private.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @class ARTWrapperSDKProxyOptions; 4 | 5 | NS_ASSUME_NONNULL_BEGIN 6 | 7 | @interface ARTWrapperSDKProxyPushDeviceRegistrations () 8 | 9 | - (instancetype)initWithPushDeviceRegistrations:(ARTPushDeviceRegistrations *)pushDeviceRegistrations 10 | proxyOptions:(ARTWrapperSDKProxyOptions *)proxyOptions NS_DESIGNATED_INITIALIZER; 11 | 12 | @end 13 | 14 | NS_ASSUME_NONNULL_END 15 | -------------------------------------------------------------------------------- /Source/SocketRocket/Internal/Utilities/ARTSRRandom.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2016-present, Facebook, Inc. 3 | // All rights reserved. 4 | // 5 | // This source code is licensed under the BSD-style license found in the 6 | // LICENSE file in the root directory of this source tree. An additional grant 7 | // of patent rights can be found in the PATENTS file in the same directory. 8 | // 9 | 10 | #import 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | extern NSData *ARTSRRandomData(NSUInteger length); 15 | 16 | NS_ASSUME_NONNULL_END 17 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTAnnotation+Private.h: -------------------------------------------------------------------------------- 1 | @import Foundation; 2 | #import 3 | #import "ARTDataEncoder.h" 4 | 5 | NS_ASSUME_NONNULL_BEGIN 6 | 7 | @interface ARTAnnotation () 8 | 9 | @property (nonatomic, readonly) BOOL isIdEmpty; 10 | 11 | - (id)decodeDataWithEncoder:(ARTDataEncoder *)encoder error:(NSError *__nullable*__nullable)error; 12 | - (id)encodeDataWithEncoder:(ARTDataEncoder *)encoder error:(NSError *__nullable*__nullable)error; 13 | 14 | - (NSInteger)annotationSize; 15 | 16 | @end 17 | 18 | NS_ASSUME_NONNULL_END 19 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTWrapperSDKProxyPushChannelSubscriptions+Private.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @class ARTWrapperSDKProxyOptions; 4 | 5 | NS_ASSUME_NONNULL_BEGIN 6 | 7 | @interface ARTWrapperSDKProxyPushChannelSubscriptions () 8 | 9 | - (instancetype)initWithPushChannelSubscriptions:(ARTPushChannelSubscriptions *)pushChannelSubscriptions 10 | proxyOptions:(ARTWrapperSDKProxyOptions *)proxyOptions NS_DESIGNATED_INITIALIZER; 11 | 12 | @end 13 | 14 | NS_ASSUME_NONNULL_END 15 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTBaseMessage+Private.h: -------------------------------------------------------------------------------- 1 | @import Foundation; 2 | #import 3 | #import "ARTDataEncoder.h" 4 | #import 5 | 6 | NS_ASSUME_NONNULL_BEGIN 7 | 8 | @interface ARTBaseMessage () 9 | 10 | @property (nonatomic, readonly) BOOL isIdEmpty; 11 | 12 | - (id __nonnull)decodeWithEncoder:(ARTDataEncoder*)encoder error:(NSError *__nullable*__nullable)error; 13 | - (id __nonnull)encodeWithEncoder:(ARTDataEncoder*)encoder error:(NSError *__nullable*__nullable)error; 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /Source/ARTPublicRealtimeChannelUnderlyingObjects.m: -------------------------------------------------------------------------------- 1 | #ifdef ABLY_SUPPORTS_PLUGINS 2 | 3 | #import "ARTPublicRealtimeChannelUnderlyingObjects.h" 4 | 5 | @implementation APDefaultPublicRealtimeChannelUnderlyingObjects 6 | 7 | @synthesize client = _client; 8 | @synthesize channel = _channel; 9 | 10 | - (instancetype)initWithClient:(id)client channel:(id)channel { 11 | if (self = [super init]) { 12 | _client = client; 13 | _channel = channel; 14 | } 15 | 16 | return self; 17 | } 18 | 19 | @end 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTNSMutableURLRequest+ARTUtils.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | NS_ASSUME_NONNULL_BEGIN 4 | 5 | @interface NSMutableURLRequest (ARTUtils) 6 | 7 | /** 8 | Note: this method is using URLComponents to deconstruct URL of this request then it replacing `host` with new one. 9 | If for some reasons new URL constructed by URLComponents is `nil`, old URL is a valiid URL for this request. 10 | */ 11 | - (void)replaceHostWith:(NSString *)host; 12 | - (void)appendQueryItem:(NSURLQueryItem *)item; 13 | 14 | @end 15 | 16 | NS_ASSUME_NONNULL_END 17 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTPresenceMessage+Private.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface ARTPresenceMessage () 4 | 5 | /** 6 | Returns whether this presenceMessage is synthesized, i.e. was not actually sent by the connection (usually means a leave event sent 15s after a disconnection). This is useful because synthesized messages cannot be compared for newness by id lexicographically - RTP2b1. 7 | */ 8 | - (BOOL)isSynthesized; 9 | 10 | - (NSArray *)parseId; 11 | - (NSInteger)msgSerialFromId; 12 | - (NSInteger)indexFromId; 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /Source/SocketRocket/Internal/NSRunLoop+ARTSRWebSocketPrivate.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2016-present, Facebook, Inc. 3 | // All rights reserved. 4 | // 5 | // This source code is licensed under the BSD-style license found in the 6 | // LICENSE file in the root directory of this source tree. An additional grant 7 | // of patent rights can be found in the PATENTS file in the same directory. 8 | // 9 | 10 | #import "NSRunLoop+ARTSRWebSocket.h" 11 | 12 | // Empty function that force links the object file for the category. 13 | extern void import_NSRunLoop_ARTSRWebSocket(void); 14 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTClientInformation+Private.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | NS_ASSUME_NONNULL_BEGIN 4 | 5 | extern NSString *const ARTClientInformation_libraryVersion; 6 | 7 | @interface ARTClientInformation (Private) 8 | 9 | + (NSString *)libraryAgentIdentifier; 10 | + (NSString *)platformAgentIdentifier; 11 | 12 | // The resulting string only includes the given agents; it does not insert any default agents. 13 | + (NSString *)agentIdentifierForAgents:(NSDictionary *)agents; 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /Source/SocketRocket/Internal/NSURLRequest+ARTSRWebSocketPrivate.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2016-present, Facebook, Inc. 3 | // All rights reserved. 4 | // 5 | // This source code is licensed under the BSD-style license found in the 6 | // LICENSE file in the root directory of this source tree. An additional grant 7 | // of patent rights can be found in the PATENTS file in the same directory. 8 | // 9 | 10 | #import "NSURLRequest+ARTSRWebSocket.h" 11 | 12 | // Empty function that force links the object file for the category. 13 | extern void import_NSURLRequest_ARTSRWebSocket(void); 14 | -------------------------------------------------------------------------------- /Ably-SoakTest-App/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Ably-SoakTest-App 4 | // 5 | // Created by Toni Cárdenas on 16/11/2019. 6 | // Copyright © 2019 Ably. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 14 | // Override point for customization after application launch. 15 | return true 16 | } 17 | } 18 | 19 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTPendingMessage.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import "ARTQueuedMessage.h" 3 | 4 | NS_ASSUME_NONNULL_BEGIN 5 | 6 | /// :nodoc: 7 | @interface ARTPendingMessage : ARTQueuedMessage 8 | 9 | - (instancetype)initWithProtocolMessage:(ARTProtocolMessage *)msg sentCallback:(nullable ARTCallback)sentCallback ackCallback:(nullable ARTStatusCallback)ackCallback UNAVAILABLE_ATTRIBUTE; 10 | 11 | - (instancetype)initWithProtocolMessage:(ARTProtocolMessage *)msg ackCallback:(nullable ARTStatusCallback)ackCallback; 12 | 13 | @end 14 | 15 | NS_ASSUME_NONNULL_END 16 | -------------------------------------------------------------------------------- /Source/ARTMsgPackEncoder.m: -------------------------------------------------------------------------------- 1 | #import "ARTMsgPackEncoder.h" 2 | #import 3 | 4 | @implementation ARTMsgPackEncoder 5 | 6 | - (NSString *)mimeType { 7 | return @"application/x-msgpack"; 8 | } 9 | 10 | - (ARTEncoderFormat)format { 11 | return ARTEncoderFormatMsgPack; 12 | } 13 | 14 | - (NSString *)formatAsString { 15 | return @"msgpack"; 16 | } 17 | 18 | - (id)decode:(NSData *)data error:(NSError **)error { 19 | return [data messagePackParse]; 20 | } 21 | 22 | - (NSData *)encode:(id)obj error:(NSError **)error { 23 | return [obj messagePack]; 24 | } 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /Source/ARTNSError+ARTUtils.m: -------------------------------------------------------------------------------- 1 | #import "ARTNSError+ARTUtils.h" 2 | #import "ARTStatus.h" 3 | 4 | @implementation NSError (ARTUtils) 5 | 6 | + (NSError *)copyFromError:(NSError *)error withRequestId:(nullable NSString *)requestId { 7 | NSMutableDictionary *mutableInfo = [NSMutableDictionary dictionaryWithDictionary:error.userInfo]; 8 | mutableInfo[ARTErrorInfoRequestIdKey] = requestId; 9 | 10 | return [NSError errorWithDomain:error.domain code:error.code userInfo:mutableInfo]; 11 | } 12 | 13 | - (NSString *)requestId { 14 | return self.userInfo[ARTErrorInfoRequestIdKey]; 15 | } 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTDeviceStorage.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | NS_ASSUME_NONNULL_BEGIN 5 | 6 | // Instances of ARTDeviceStorage should expect to have their methods called 7 | // from any thread. 8 | /// :nodoc: 9 | @protocol ARTDeviceStorage 10 | - (nullable id)objectForKey:(NSString *)key; 11 | - (void)setObject:(nullable id)value forKey:(NSString *)key; 12 | - (nullable NSString *)secretForDevice:(ARTDeviceId *)deviceId; 13 | - (void)setSecret:(nullable NSString *)value forDevice:(ARTDeviceId *)deviceId; 14 | @end 15 | 16 | NS_ASSUME_NONNULL_END 17 | -------------------------------------------------------------------------------- /Source/ARTNSArray+ARTFunctional.m: -------------------------------------------------------------------------------- 1 | #import "ARTNSArray+ARTFunctional.h" 2 | 3 | @implementation NSArray (ARTFunctional) 4 | 5 | - (NSArray *)artMap:(id (^)(id))f { 6 | NSMutableArray *array = [NSMutableArray arrayWithCapacity:self.count]; 7 | for (id e in self) { 8 | [array addObject:(f(e))]; 9 | } 10 | return array; 11 | } 12 | 13 | - (NSArray *)artFilter:(BOOL (^)(id))f { 14 | NSMutableArray *array = [NSMutableArray arrayWithCapacity:self.count]; 15 | for (id e in self) { 16 | if (f(e)) { 17 | [array addObject:e]; 18 | } 19 | } 20 | return array; 21 | } 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /Examples/Tests/Tests/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // Tests 4 | // 5 | // Created by Toni Cárdenas on 11/5/16. 6 | // Copyright © 2016 Ably. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ViewController: UIViewController { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | // Do any additional setup after loading the view, typically from a nib. 16 | } 17 | 18 | override func didReceiveMemoryWarning() { 19 | super.didReceiveMemoryWarning() 20 | // Dispose of any resources that can be recreated. 21 | } 22 | 23 | 24 | } 25 | 26 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTConnectionDetails+Private.h: -------------------------------------------------------------------------------- 1 | #import "ARTConnectionDetails.h" 2 | 3 | #ifdef ABLY_SUPPORTS_PLUGINS 4 | @import _AblyPluginSupportPrivate; 5 | #endif 6 | 7 | #ifdef ABLY_SUPPORTS_PLUGINS 8 | @interface ARTConnectionDetails () 9 | @end 10 | #endif 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface ARTConnectionDetails () 15 | 16 | @property (readwrite, nonatomic, nullable) NSString *clientId; 17 | @property (readwrite, nonatomic, nullable) NSString *connectionKey; 18 | 19 | - (void)setMaxIdleInterval:(NSTimeInterval)seconds; 20 | 21 | @end 22 | 23 | NS_ASSUME_NONNULL_END 24 | -------------------------------------------------------------------------------- /Source/include/Ably/ARTMessageAnnotations.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | NS_ASSUME_NONNULL_BEGIN 5 | 6 | /** 7 | * Contains annotations summary for a message. The keys of the dict are annotation types, and the values are aggregated summaries for that annotation type. 8 | */ 9 | @interface ARTMessageAnnotations : NSObject 10 | 11 | /// An annotations summary for the message. The keys of the dict are annotation types, and the values are aggregated summaries for that annotation type. 12 | @property (nonatomic, copy, nullable) ARTJsonObject *summary; 13 | 14 | @end 15 | 16 | NS_ASSUME_NONNULL_END 17 | -------------------------------------------------------------------------------- /Source/ARTAuthDetails.m: -------------------------------------------------------------------------------- 1 | #import "ARTAuthDetails.h" 2 | 3 | @implementation ARTAuthDetails 4 | 5 | - (instancetype)initWithToken:(NSString *)token { 6 | if (self = [super init]) { 7 | _accessToken = token; 8 | } 9 | return self; 10 | } 11 | 12 | - (NSString *)description { 13 | return [NSString stringWithFormat:@"%@ - \n\t accessToken: %@; \n", [super description], self.accessToken]; 14 | } 15 | 16 | - (id)copyWithZone:(NSZone *)zone { 17 | ARTAuthDetails *authDetails = [[[self class] allocWithZone:zone] init]; 18 | authDetails.accessToken = self.accessToken; 19 | return authDetails; 20 | } 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /Source/SocketRocket/Internal/ARTSRConstants.m: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2016-present, Facebook, Inc. 3 | // All rights reserved. 4 | // 5 | // This source code is licensed under the BSD-style license found in the 6 | // LICENSE file in the root directory of this source tree. An additional grant 7 | // of patent rights can be found in the PATENTS file in the same directory. 8 | // 9 | 10 | #import "ARTSRConstants.h" 11 | 12 | size_t ARTSRDefaultBufferSize(void) { 13 | static size_t size; 14 | static dispatch_once_t onceToken; 15 | dispatch_once(&onceToken, ^{ 16 | size = getpagesize(); 17 | }); 18 | return size; 19 | } 20 | -------------------------------------------------------------------------------- /Source/ARTConnectionStateChangeParams.m: -------------------------------------------------------------------------------- 1 | #import "ARTConnectionStateChangeParams.h" 2 | 3 | @implementation ARTConnectionStateChangeParams 4 | 5 | - (instancetype)init { 6 | return [self initWithErrorInfo:nil]; 7 | } 8 | 9 | - (instancetype)initWithErrorInfo:(ARTErrorInfo *)errorInfo { 10 | return [self initWithErrorInfo:errorInfo retryAttempt:nil]; 11 | } 12 | 13 | - (instancetype)initWithErrorInfo:(ARTErrorInfo *)errorInfo retryAttempt:(ARTRetryAttempt *)retryAttempt { 14 | if (self = [super init]) { 15 | _errorInfo = errorInfo; 16 | _retryAttempt = retryAttempt; 17 | } 18 | 19 | return self; 20 | } 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /Source/include/Ably/ARTWrapperSDKProxyPushChannel.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | NS_ASSUME_NONNULL_BEGIN 5 | 6 | /** 7 | * 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. 8 | * 9 | * - Important: This class should only be used by Ably-authored SDKs. 10 | */ 11 | NS_SWIFT_SENDABLE 12 | @interface ARTWrapperSDKProxyPushChannel : NSObject 13 | 14 | - (instancetype)init NS_UNAVAILABLE; 15 | 16 | @end 17 | 18 | NS_ASSUME_NONNULL_END 19 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTDeviceDetails+Private.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @class ARTDevicePushDetails; 5 | 6 | NS_ASSUME_NONNULL_BEGIN 7 | 8 | @interface ARTDeviceDetails () 9 | 10 | @property (nonatomic, readwrite) ARTDeviceId *id; 11 | @property (nullable, nonatomic, readwrite) NSString *clientId; 12 | @property (nonatomic, readwrite) NSString *platform; 13 | @property (nonatomic, readwrite) NSString *formFactor; 14 | @property (nonatomic, readwrite) NSDictionary *metadata; 15 | @property (nonatomic, readwrite) ARTDevicePushDetails *push; 16 | 17 | @end 18 | 19 | NS_ASSUME_NONNULL_END 20 | -------------------------------------------------------------------------------- /Source/ARTNSDate+ARTUtil.m: -------------------------------------------------------------------------------- 1 | #import "ARTNSDate+ARTUtil.h" 2 | 3 | @implementation NSDate (ARTUtil) 4 | 5 | + (instancetype)artDateFromIntegerMs:(long long)ms { 6 | NSTimeInterval intervalSince1970 = ms / 1000.0; 7 | return [NSDate dateWithTimeIntervalSince1970:intervalSince1970]; 8 | } 9 | 10 | + (instancetype)artDateFromNumberMs:(NSNumber *)number { 11 | return [self artDateFromIntegerMs:[number longLongValue]]; 12 | } 13 | 14 | - (NSNumber *)artToNumberMs { 15 | return [NSNumber numberWithInteger:[self artToIntegerMs]]; 16 | } 17 | 18 | - (NSInteger)artToIntegerMs { 19 | return (NSInteger)round([self timeIntervalSince1970] * 1000.0); 20 | } 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /Source/include/Ably/ARTWrapperSDKProxyRealtimePresence.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | NS_ASSUME_NONNULL_BEGIN 5 | 6 | /** 7 | * 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. 8 | * 9 | * - Important: This class should only be used by Ably-authored SDKs. 10 | */ 11 | NS_SWIFT_SENDABLE 12 | @interface ARTWrapperSDKProxyRealtimePresence : NSObject 13 | 14 | - (instancetype)init NS_UNAVAILABLE; 15 | 16 | @end 17 | 18 | NS_ASSUME_NONNULL_END 19 | -------------------------------------------------------------------------------- /Test/AblyTestsObjC/ObjcppTest.mm: -------------------------------------------------------------------------------- 1 | // 2 | 3 | /* 4 | This file is needed to check if C++ compiler is able to work with Ably Cocoa. 5 | */ 6 | 7 | #import 8 | #import 9 | 10 | class AblyVersionTestWrapper { 11 | 12 | public: 13 | static void printVersionInfo(); 14 | }; 15 | 16 | void AblyVersionTestWrapper::printVersionInfo() { 17 | printf("Library accessed in c++ method: %s\r\n", ARTDefault.libraryVersion.UTF8String); 18 | }; 19 | 20 | 21 | @interface ObjcppTest : XCTestCase 22 | @end 23 | 24 | @implementation ObjcppTest 25 | 26 | - (void)testPrintVersionInfo { 27 | AblyVersionTestWrapper::printVersionInfo(); 28 | } 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTPluginDecodingContext.h: -------------------------------------------------------------------------------- 1 | #ifdef ABLY_SUPPORTS_PLUGINS 2 | 3 | #import 4 | @import _AblyPluginSupportPrivate; 5 | 6 | NS_ASSUME_NONNULL_BEGIN 7 | 8 | @interface ARTPluginDecodingContext: NSObject 9 | 10 | - (instancetype)initWithParentID:(nullable NSString *)parentID 11 | parentConnectionID:(nullable NSString *)parentConnectionID 12 | parentTimestamp:(nullable NSDate *)parentTimestamp 13 | indexInParent:(NSInteger)indexInParent NS_DESIGNATED_INITIALIZER; 14 | 15 | - (instancetype)init NS_UNAVAILABLE; 16 | 17 | @end 18 | 19 | NS_ASSUME_NONNULL_END 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /Source/include/Ably/ARTRealtime+WrapperSDKProxy.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @class ARTWrapperSDKProxyOptions; 4 | @class ARTWrapperSDKProxyRealtime; 5 | 6 | NS_ASSUME_NONNULL_BEGIN 7 | 8 | @interface ARTRealtime (WrapperSDKProxy) 9 | 10 | /** 11 | Creates a proxy client to be used to supply analytics information for Ably-authored SDKs. 12 | 13 | The proxy client shares the state of the `ARTRealtime` instance on which this method is called. 14 | 15 | - Important: This method should only be called by Ably-authored SDKs. 16 | */ 17 | - (ARTWrapperSDKProxyRealtime *)createWrapperSDKProxyWithOptions:(ARTWrapperSDKProxyOptions *)options; 18 | 19 | @end 20 | 21 | NS_ASSUME_NONNULL_END 22 | -------------------------------------------------------------------------------- /Source/include/Ably/ARTWrapperSDKProxyRealtimeAnnotations.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | NS_ASSUME_NONNULL_BEGIN 5 | 6 | /** 7 | * An object which wraps an instance of `ARTRealtimeAnnotations` 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. 8 | * 9 | * - Important: This class should only be used by Ably-authored SDKs. 10 | */ 11 | NS_SWIFT_SENDABLE 12 | @interface ARTWrapperSDKProxyRealtimeAnnotations : NSObject 13 | 14 | - (instancetype)init NS_UNAVAILABLE; 15 | 16 | @end 17 | 18 | NS_ASSUME_NONNULL_END 19 | -------------------------------------------------------------------------------- /Source/ARTNSMutableURLRequest+ARTPaginated.m: -------------------------------------------------------------------------------- 1 | #import "ARTNSMutableURLRequest+ARTPaginated.h" 2 | 3 | @implementation NSMutableURLRequest (ARTPaginated) 4 | 5 | + (NSMutableURLRequest *)requestWithPath:(NSString *)path relativeTo:(NSURLRequest *)request { 6 | if (!path) { 7 | return nil; 8 | } 9 | NSURL *url = [NSURL URLWithString:path relativeToURL:request.URL]; 10 | NSMutableURLRequest *newRequest = [NSMutableURLRequest requestWithURL:url]; 11 | 12 | // Copy headers from the original request to preserve custom headers (like X-Ably-Version) 13 | [newRequest setAllHTTPHeaderFields:[request allHTTPHeaderFields]]; 14 | 15 | return newRequest; 16 | } 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /Source/SocketRocket/Internal/Utilities/ARTSRHash.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2016-present, Facebook, Inc. 3 | // All rights reserved. 4 | // 5 | // This source code is licensed under the BSD-style license found in the 6 | // LICENSE file in the root directory of this source tree. An additional grant 7 | // of patent rights can be found in the PATENTS file in the same directory. 8 | // 9 | 10 | #import 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | extern NSData *ARTSRSHA1HashFromString(NSString *string); 15 | extern NSData *ARTSRSHA1HashFromBytes(const char *bytes, size_t length); 16 | 17 | extern NSString *ARTSRBase64EncodedStringFromData(NSData *data); 18 | 19 | NS_ASSUME_NONNULL_END 20 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTWebSocketFactory.h: -------------------------------------------------------------------------------- 1 | @import Foundation; 2 | 3 | @protocol ARTWebSocket; 4 | @class ARTInternalLog; 5 | 6 | NS_ASSUME_NONNULL_BEGIN 7 | 8 | /** 9 | A factory for creating an `ARTWebSocket` object. 10 | */ 11 | NS_SWIFT_NAME(WebSocketFactory) 12 | @protocol ARTWebSocketFactory 13 | 14 | - (id)createWebSocketWithURLRequest:(NSURLRequest *)request logger:(nullable ARTInternalLog *)logger; 15 | 16 | @end 17 | 18 | /** 19 | The implementation of `ARTWebSocketFactory` that should be used in non-test code. 20 | */ 21 | NS_SWIFT_NAME(DefaultWebSocketFactory) 22 | @interface ARTDefaultWebSocketFactory: NSObject 23 | @end 24 | 25 | NS_ASSUME_NONNULL_END 26 | -------------------------------------------------------------------------------- /Source/SocketRocket/Internal/RunLoop/ARTSRRunLoopThread.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2012 Square Inc. 3 | // Portions Copyright (c) 2016-present, Facebook, Inc. 4 | // 5 | // All rights reserved. 6 | // 7 | // This source code is licensed under the BSD-style license found in the 8 | // LICENSE file in the root directory of this source tree. An additional grant 9 | // of patent rights can be found in the PATENTS file in the same directory. 10 | // 11 | 12 | #import 13 | 14 | NS_ASSUME_NONNULL_BEGIN 15 | 16 | @interface ARTSRRunLoopThread : NSThread 17 | 18 | @property (nonatomic, readonly) NSRunLoop *runLoop; 19 | 20 | + (instancetype)sharedThread; 21 | 22 | @end 23 | 24 | NS_ASSUME_NONNULL_END 25 | -------------------------------------------------------------------------------- /Source/include/Ably/ARTWrapperSDKProxyPushDeviceRegistrations.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | NS_ASSUME_NONNULL_BEGIN 5 | 6 | /** 7 | * 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. 8 | * 9 | * - Important: This class should only be used by Ably-authored SDKs. 10 | */ 11 | NS_SWIFT_SENDABLE 12 | @interface ARTWrapperSDKProxyPushDeviceRegistrations : NSObject 13 | 14 | - (instancetype)init NS_UNAVAILABLE; 15 | 16 | @end 17 | 18 | NS_ASSUME_NONNULL_END 19 | -------------------------------------------------------------------------------- /Test/AblyTests/Test Utilities/BackoffCoefficients.swift: -------------------------------------------------------------------------------- 1 | /// An infinite sequence of `Double` values, providing the sequence of "backoff coefficients" defined by RTB1a. All iterations of all instances of `BackoffCoefficients` return the same sequence of numbers. 2 | struct BackoffCoefficients: Sequence { 3 | struct Iterator: IteratorProtocol { 4 | private var retryNumber = 1 5 | 6 | mutating func next() -> Double? { 7 | let backoffCoefficient = Swift.min((Double(retryNumber) + 2) / 3.0, 2.0) 8 | retryNumber += 1 9 | return backoffCoefficient 10 | } 11 | } 12 | 13 | func makeIterator() -> Iterator { 14 | return Iterator() 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Source/include/Ably/ARTWrapperSDKProxyPushChannelSubscriptions.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | NS_ASSUME_NONNULL_BEGIN 5 | 6 | /** 7 | * 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. 8 | * 9 | * - Important: This class should only be used by Ably-authored SDKs. 10 | */ 11 | NS_SWIFT_SENDABLE 12 | @interface ARTWrapperSDKProxyPushChannelSubscriptions : NSObject 13 | 14 | - (instancetype)init NS_UNAVAILABLE; 15 | 16 | @end 17 | 18 | NS_ASSUME_NONNULL_END 19 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTRestAnnotations+Private.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import "ARTQueuedDealloc.h" 3 | 4 | NS_ASSUME_NONNULL_BEGIN 5 | 6 | @class ARTRestChannelInternal; 7 | @class ARTInternalLog; 8 | 9 | @interface ARTRestAnnotationsInternal : NSObject 10 | 11 | - (instancetype)initWithChannel:(ARTRestChannelInternal *)channel logger:(ARTInternalLog *)logger; 12 | 13 | @end 14 | 15 | @interface ARTRestAnnotations () 16 | 17 | @property (nonatomic, readonly) ARTRestAnnotationsInternal *internal; 18 | 19 | - (instancetype)initWithInternal:(ARTRestAnnotationsInternal *)internal queuedDealloc:(ARTQueuedDealloc *)dealloc; 20 | 21 | @end 22 | 23 | NS_ASSUME_NONNULL_END 24 | -------------------------------------------------------------------------------- /Examples/SPM/Package.resolved: -------------------------------------------------------------------------------- 1 | { 2 | "object": { 3 | "pins": [ 4 | { 5 | "package": "AblyDeltaCodec", 6 | "repositoryURL": "https://github.com/ably/delta-codec-cocoa", 7 | "state": { 8 | "branch": null, 9 | "revision": "3ee62ea40a63996b55818d44b3f0e56d8753be88", 10 | "version": "1.3.3" 11 | } 12 | }, 13 | { 14 | "package": "msgpack", 15 | "repositoryURL": "https://github.com/rvi/msgpack-objective-C", 16 | "state": { 17 | "branch": null, 18 | "revision": "3e36b48e04ecd756cb927bd5f5b9bf6d45e475f9", 19 | "version": "0.4.0" 20 | } 21 | } 22 | ] 23 | }, 24 | "version": 1 25 | } 26 | -------------------------------------------------------------------------------- /Scripts/add-licenses-to-carthage-output.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | ZIP_NAME="Ably.framework.zip" 6 | TEMPDIR=`mktemp -d` 7 | BUILD_DIR=`pwd` 8 | 9 | # Unzip Carthage's output into a temporary directory. 10 | cp "${ZIP_NAME}" "${TEMPDIR}" 11 | unzip "${TEMPDIR}/${ZIP_NAME}" -d "${TEMPDIR}" 12 | 13 | # Copy our LICENSE files across. 14 | cp LICENSE "${TEMPDIR}/Carthage" 15 | mkdir "${TEMPDIR}/Carthage/SocketRocket" 16 | cp Source/SocketRocket/LICENSE "${TEMPDIR}/Carthage/SocketRocket" 17 | 18 | # Re-zip (replacing the original zip file) then clean up. 19 | cd "${TEMPDIR}" 20 | zip --recurse-paths --symlinks Carthage Carthage 21 | cp "${TEMPDIR}/Carthage.zip" "${BUILD_DIR}/${ZIP_NAME}" 22 | rm -rf "${TEMPDIR}" 23 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTNSDictionary+ARTDictionaryUtil.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface NSDictionary (ARTDictionaryUtil) 4 | 5 | - (NSString *)artString:(id)key; 6 | - (NSNumber *)artNumber:(id)key; 7 | - (NSDate *)artTimestamp:(id)key; 8 | - (NSArray *)artArray:(id)key; 9 | - (NSDictionary *)artDictionary:(id)key; 10 | - (NSInteger)artInteger:(id)key; 11 | - (BOOL)artBoolean:(id)key; 12 | 13 | - (id)artTyped:(Class)cls key:(id)key; 14 | 15 | /** 16 | * Maps dictionary values using the provided block function. 17 | * @param f Block function that transforms each value 18 | * @return New dictionary with transformed values 19 | */ 20 | - (NSDictionary *)artMap:(id(^)(id key, id value))f; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTNSMutableRequest+ARTPush.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #import 4 | 5 | @class ARTLocalDevice; 6 | @class ARTInternalLog; 7 | 8 | NS_ASSUME_NONNULL_BEGIN 9 | 10 | @interface NSMutableURLRequest (ARTPush) 11 | 12 | - (void)setDeviceAuthentication:(ARTDeviceId *)deviceId localDevice:(ARTLocalDevice *)localDevice; 13 | - (void)setDeviceAuthentication:(ARTDeviceId *)deviceId localDevice:(ARTLocalDevice *)localDevice logger:(nullable ARTInternalLog *)logger; 14 | - (void)setDeviceAuthentication:(ARTLocalDevice *)localDevice; 15 | - (void)setDeviceAuthentication:(ARTLocalDevice *)localDevice logger:(nullable ARTInternalLog *)logger; 16 | 17 | @end 18 | 19 | NS_ASSUME_NONNULL_END 20 | -------------------------------------------------------------------------------- /Source/include/Ably/ARTWrapperSDKProxyPush.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @class ARTWrapperSDKProxyPushAdmin; 5 | 6 | NS_ASSUME_NONNULL_BEGIN 7 | 8 | /** 9 | * 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. 10 | * 11 | * - Important: This class should only be used by Ably-authored SDKs. 12 | */ 13 | NS_SWIFT_SENDABLE 14 | @interface ARTWrapperSDKProxyPush : NSObject 15 | 16 | - (instancetype)init NS_UNAVAILABLE; 17 | 18 | @property (readonly) ARTWrapperSDKProxyPushAdmin *admin; 19 | 20 | @end 21 | 22 | NS_ASSUME_NONNULL_END 23 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTClientOptions+TestConfiguration.h: -------------------------------------------------------------------------------- 1 | @import Foundation; 2 | #import 3 | 4 | @class ARTTestClientOptions; 5 | 6 | NS_ASSUME_NONNULL_BEGIN 7 | 8 | /** 9 | Provides an interface for injecting additional configuration into `ARTRest` or `ARTRealtime` instances. 10 | 11 | This is for anything that test code wishes to be able to configure but which should not be part of the public API of these classes. 12 | */ 13 | @interface ARTClientOptions () 14 | 15 | /** 16 | Defaults to a new instance of `ARTTestClientOptions` (whose properties all have their default values). 17 | */ 18 | @property (nonatomic, copy) ARTTestClientOptions *testOptions; 19 | 20 | @end 21 | 22 | NS_ASSUME_NONNULL_END 23 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTWebSocketTransport.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #import "ARTRealtimeTransport.h" 4 | 5 | @class ARTClientOptions; 6 | @class ARTRest; 7 | @protocol ARTWebSocketFactory; 8 | 9 | NS_ASSUME_NONNULL_BEGIN 10 | 11 | @interface ARTWebSocketTransport : NSObject 12 | 13 | - (instancetype)init UNAVAILABLE_ATTRIBUTE; 14 | 15 | - (instancetype)initWithRest:(ARTRestInternal *)rest options:(ARTClientOptions *)options resumeKey:(nullable NSString *)resumeKey logger:(ARTInternalLog *)logger webSocketFactory:(id)webSocketFactory NS_DESIGNATED_INITIALIZER; 16 | 17 | @property (readonly, nonatomic) NSString *resumeKey; 18 | 19 | @end 20 | 21 | NS_ASSUME_NONNULL_END 22 | -------------------------------------------------------------------------------- /Source/SocketRocket/Internal/Utilities/ARTSRSIMDHelpers.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2016-present, Facebook, Inc. 3 | // All rights reserved. 4 | // 5 | // This source code is licensed under the BSD-style license found in the 6 | // LICENSE file in the root directory of this source tree. An additional grant 7 | // of patent rights can be found in the PATENTS file in the same directory. 8 | // 9 | 10 | #import 11 | 12 | /** 13 | Unmask bytes using XOR via SIMD. 14 | 15 | @param bytes The bytes to unmask. 16 | @param length The number of bytes to unmask. 17 | @param maskKey The mask to XOR with MUST be of length sizeof(uint32_t). 18 | */ 19 | void ARTSRMaskBytesSIMD(uint8_t *bytes, size_t length, uint8_t *maskKey); 20 | -------------------------------------------------------------------------------- /Scripts/local_dev_upload_test_results.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Allows us to upload test results to an instance of the test 4 | # observability server running locally on a developer's machine. 5 | 6 | export TEST_OBSERVABILITY_SERVER_AUTH_KEY="abc123" 7 | export GITHUB_SHA="fakesha" 8 | export GITHUB_REF_NAME="fake-ref-name" 9 | export GITHUB_RETENTION_DAYS="30" 10 | export GITHUB_ACTION="fake-action" 11 | export GITHUB_RUN_NUMBER="132423" 12 | export GITHUB_RUN_ID="fake-run-id" 13 | export GITHUB_RUN_ATTEMPT="1" 14 | export GITHUB_BASE_REF="main" 15 | export GITHUB_HEAD_REF="my-branch" 16 | export GITHUB_JOB="fake-job" 17 | export GITHUB_REPOSITORY="ably/ably-cocoa" 18 | 19 | ./Scripts/upload_test_results.sh --upload-server-base-url "http://localhost:3000" 20 | -------------------------------------------------------------------------------- /Test/Ably.xctestplan: -------------------------------------------------------------------------------- 1 | { 2 | "configurations" : [ 3 | { 4 | "id" : "1D9DE6FE-6E89-4989-AC97-7DE3BA810C74", 5 | "name" : "Test Scheme Action", 6 | "options" : { 7 | 8 | } 9 | } 10 | ], 11 | "defaultOptions" : { 12 | "codeCoverage" : false, 13 | "language" : "en", 14 | "region" : "US" 15 | }, 16 | "testTargets" : [ 17 | { 18 | "target" : { 19 | "containerPath" : "container:", 20 | "identifier" : "AblyTests", 21 | "name" : "AblyTests" 22 | } 23 | }, 24 | { 25 | "target" : { 26 | "containerPath" : "container:", 27 | "identifier" : "AblyTestsObjC", 28 | "name" : "AblyTestsObjC" 29 | } 30 | } 31 | ], 32 | "version" : 1 33 | } 34 | -------------------------------------------------------------------------------- /.github/workflows/check-spm.yaml: -------------------------------------------------------------------------------- 1 | # This workflow checks that the SPM version of the library (which includes additional code for plugin support compared to the Xcode version) compiles and does not have any warnings. 2 | 3 | name: "Check SPM build" 4 | 5 | on: 6 | workflow_dispatch: 7 | pull_request: 8 | push: 9 | branches: 10 | - main 11 | 12 | jobs: 13 | build: 14 | runs-on: macos-15 15 | 16 | steps: 17 | - uses: actions/checkout@v4 18 | with: 19 | submodules: true 20 | - uses: maxim-lobanov/setup-xcode@v1 21 | with: 22 | xcode-version: 16.4 23 | 24 | # https://forums.swift.org/t/warnings-as-errors-for-libraries-frameworks/58393/2 25 | - run: swift build -Xswiftc -warnings-as-errors 26 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTFallback.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | NS_ASSUME_NONNULL_BEGIN 4 | 5 | @class ARTHttpResponse; 6 | @class ARTClientOptions; 7 | 8 | /// :nodoc: 9 | @interface ARTFallback : NSObject 10 | 11 | /** 12 | Init with fallback hosts array. 13 | */ 14 | - (instancetype)initWithFallbackHosts:(nullable NSArray *)fallbackHosts shuffleArray:(void (^)(NSMutableArray *))shuffleArray; 15 | - (instancetype)init NS_UNAVAILABLE; 16 | 17 | /** 18 | Returns a random fallback host, returns null when all hosts have been popped. 19 | */ 20 | - (nullable NSString *)popFallbackHost; 21 | 22 | /** 23 | Returns true if all hosts have been popped without popping one. 24 | */ 25 | - (BOOL)isEmpty; 26 | 27 | @end 28 | 29 | NS_ASSUME_NONNULL_END 30 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTPluginAPI.h: -------------------------------------------------------------------------------- 1 | #ifdef ABLY_SUPPORTS_PLUGINS 2 | 3 | @import Foundation; 4 | @import _AblyPluginSupportPrivate; 5 | 6 | NS_ASSUME_NONNULL_BEGIN 7 | 8 | /// Our implementation of `APPluginAPIProtocol`, which allows Ably-authored plugins to access the internals of this SDK. 9 | @interface ARTPluginAPI: NSObject 10 | 11 | /// If not already registered, registers an instance of this class on the shared `APDependencyStore` instance. 12 | /// 13 | /// This needs to be called before any plugin tries to fetch a `PluginAPI` from the `APDependencyStore`. Ensure that you call it as part of the initialization of any type that a plugin may try to extend. 14 | + (void)registerSelf; 15 | 16 | @end 17 | 18 | NS_ASSUME_NONNULL_END 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /Source/SocketRocket/NSRunLoop+ARTSRWebSocket.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2012 Square Inc. 3 | // Portions Copyright (c) 2016-present, Facebook, Inc. 4 | // 5 | // All rights reserved. 6 | // 7 | // This source code is licensed under the BSD-style license found in the 8 | // LICENSE file in the root directory of this source tree. An additional grant 9 | // of patent rights can be found in the PATENTS file in the same directory. 10 | // 11 | 12 | #import 13 | 14 | NS_ASSUME_NONNULL_BEGIN 15 | 16 | @interface NSRunLoop (ARTSRWebSocket) 17 | 18 | /** 19 | Default run loop that will be used to schedule all instances of `ARTSRWebSocket`. 20 | 21 | @return An instance of `NSRunLoop`. 22 | */ 23 | + (NSRunLoop *)ARTSR_networkRunLoop; 24 | 25 | @end 26 | 27 | NS_ASSUME_NONNULL_END 28 | -------------------------------------------------------------------------------- /Test/AblyTests/Tests/DefaultJitterCoefficientGeneratorTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import Ably.Private 3 | 4 | class DefaultJitterCoefficientGeneratorTests: XCTestCase { 5 | func test_generatesValuesInExpectedRange() { 6 | let generator = DefaultJitterCoefficientGenerator() 7 | let generatedCoefficients = (1...100).map { _ in generator.generateJitterCoefficient() } 8 | 9 | XCTAssertTrue(generatedCoefficients.allSatisfy { (0.8...1.0).contains($0) }) 10 | } 11 | 12 | func test_generatesAVarietyOfValues() { 13 | let generator = DefaultJitterCoefficientGenerator() 14 | let generatedCoefficients = (1...100).map { _ in generator.generateJitterCoefficient() } 15 | 16 | XCTAssertGreaterThan(Set(generatedCoefficients).count, 95) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Examples/AblyPush/AblyPushExample/Assets.xcassets/ably-logo.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "ably-brand-light-mode 1.pdf", 5 | "idiom" : "universal" 6 | }, 7 | { 8 | "appearances" : [ 9 | { 10 | "appearance" : "luminosity", 11 | "value" : "light" 12 | } 13 | ], 14 | "filename" : "ably-brand-light-mode.pdf", 15 | "idiom" : "universal" 16 | }, 17 | { 18 | "appearances" : [ 19 | { 20 | "appearance" : "luminosity", 21 | "value" : "dark" 22 | } 23 | ], 24 | "filename" : "ably-brand-dark-mode.pdf", 25 | "idiom" : "universal" 26 | } 27 | ], 28 | "info" : { 29 | "author" : "xcode", 30 | "version" : 1 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Source/ARTAttachRequestParams.m: -------------------------------------------------------------------------------- 1 | #import "ARTAttachRequestParams.h" 2 | 3 | @implementation ARTAttachRequestParams 4 | 5 | - (instancetype)initWithReason:(ARTErrorInfo *)reason { 6 | return [self initWithReason:reason channelSerial:nil]; 7 | } 8 | 9 | - (instancetype)initWithReason:(ARTErrorInfo *)reason channelSerial:(NSString *)channelSerial { 10 | return [self initWithReason:reason channelSerial:channelSerial retryAttempt:nil]; 11 | } 12 | 13 | - (instancetype)initWithReason:(ARTErrorInfo *)reason channelSerial:(NSString *)channelSerial retryAttempt:(ARTRetryAttempt *)retryAttempt { 14 | if (self = [super init]) { 15 | _reason = reason; 16 | _channelSerial = channelSerial; 17 | _retryAttempt = retryAttempt; 18 | } 19 | 20 | return self; 21 | } 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /Source/ARTLogAdapter.m: -------------------------------------------------------------------------------- 1 | #import "ARTLogAdapter.h" 2 | #import "ARTLogAdapter+Testing.h" 3 | #import "ARTLog.h" 4 | 5 | @implementation ARTLogAdapter 6 | 7 | - (instancetype)initWithLogger:(ARTLog *)logger { 8 | if (self = [super init]) { 9 | _logger = logger; 10 | } 11 | 12 | return self; 13 | } 14 | 15 | - (void)log:(NSString *)message withLevel:(ARTLogLevel)level file:(NSString *)fileName line:(NSInteger)line { 16 | NSString *const augmentedMessage = [NSString stringWithFormat:@"(%@:%ld) %@", fileName, (long)line, message]; 17 | [self.logger log:augmentedMessage withLevel:level]; 18 | } 19 | 20 | - (ARTLogLevel)logLevel { 21 | return self.logger.logLevel; 22 | } 23 | 24 | - (void)setLogLevel:(ARTLogLevel)logLevel { 25 | self.logger.logLevel = logLevel; 26 | } 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTLog+Private.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | NS_ASSUME_NONNULL_BEGIN 4 | 5 | @interface ARTLogLine : NSObject 6 | 7 | @property(nonatomic, readonly) NSDate *date; 8 | @property(nonatomic, readonly) ARTLogLevel level; 9 | @property(nonatomic, readonly) NSString *message; 10 | 11 | - (instancetype)initWithDate:(NSDate *)date level:(ARTLogLevel)level message:(NSString *)message; 12 | 13 | - (NSString *)toString; 14 | 15 | @end 16 | 17 | @interface ARTLog () 18 | 19 | @property (readonly) NSArray *captured; 20 | @property (readonly) NSArray *history; 21 | 22 | - (instancetype)initCapturingOutput:(BOOL)capturing; 23 | - (instancetype)initCapturingOutput:(BOOL)capturing historyLines:(NSUInteger)historyLines; 24 | 25 | @end 26 | 27 | NS_ASSUME_NONNULL_END 28 | -------------------------------------------------------------------------------- /Source/ARTNSMutableRequest+ARTRest.m: -------------------------------------------------------------------------------- 1 | #import "ARTNSMutableRequest+ARTRest.h" 2 | 3 | #import "ARTEncoder.h" 4 | 5 | @implementation NSMutableURLRequest (ARTRest) 6 | 7 | - (void)setAcceptHeader:(id)defaultEncoder encoders:(NSDictionary> *)encoders { 8 | NSMutableArray *allEncoders = [NSMutableArray arrayWithArray:[encoders.allValues valueForKeyPath:@"mimeType"]]; 9 | NSString *defaultMimetype = [defaultEncoder mimeType]; 10 | // Make the mime type of the default encoder the first element of the Accept header field 11 | [allEncoders removeObject:defaultMimetype]; 12 | [allEncoders insertObject:defaultMimetype atIndex:0]; 13 | NSString *accept = [allEncoders componentsJoinedByString:@","]; 14 | [self setValue:accept forHTTPHeaderField:@"Accept"]; 15 | } 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTHttp.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #import 4 | 5 | @class ARTErrorInfo; 6 | @class ARTClientOptions; 7 | @class ARTInternalLog; 8 | 9 | @protocol ARTEncoder; 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | /// :nodoc: 14 | @protocol ARTHTTPExecutor 15 | 16 | - (nullable NSObject *)executeRequest:(NSURLRequest *)request 17 | completion:(nullable ARTURLRequestCallback)callback; 18 | 19 | @end 20 | 21 | /// :nodoc: 22 | @interface ARTHttp : NSObject 23 | 24 | + (void)setURLSessionClass:(Class)urlSessionClass; 25 | 26 | - (instancetype)init UNAVAILABLE_ATTRIBUTE; 27 | - (instancetype)initWithQueue:(dispatch_queue_t)queue logger:(ARTInternalLog *)logger; 28 | 29 | @end 30 | 31 | NS_ASSUME_NONNULL_END 32 | -------------------------------------------------------------------------------- /Ably-SoakTest-AppUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Source/include/Ably/ARTLocalDevice.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @class ARTDeviceIdentityTokenDetails; 5 | 6 | NS_ASSUME_NONNULL_BEGIN 7 | 8 | /** 9 | * Contains the device identity token and secret of a device. `ARTLocalDevice` extends `ARTDeviceDetails`. 10 | */ 11 | NS_SWIFT_SENDABLE 12 | @interface ARTLocalDevice : ARTDeviceDetails 13 | 14 | /** 15 | * A unique device identity token used to communicate with APNS. 16 | */ 17 | @property (nullable, nonatomic, readonly) ARTDeviceIdentityTokenDetails *identityTokenDetails; 18 | 19 | /** 20 | * A unique device secret generated by the Ably SDK. 21 | */ 22 | @property (nullable, nonatomic, readonly) ARTDeviceSecret *secret; 23 | 24 | /// :nodoc: 25 | - (instancetype)init NS_UNAVAILABLE; 26 | 27 | @end 28 | 29 | NS_ASSUME_NONNULL_END 30 | -------------------------------------------------------------------------------- /Source/include/Ably/AblyInternal.h: -------------------------------------------------------------------------------- 1 | // This header contains imports of API that, whilst public, is intended for use only by Ably-authored SDKs and thus should be excluded from the Jazzy-generated documentation. 2 | 3 | #import 4 | #import 5 | #import 6 | #import 7 | #import 8 | #import 9 | #import 10 | #import 11 | #import 12 | #import 13 | #import 14 | #import 15 | -------------------------------------------------------------------------------- /Source/Info-tvOS.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | $(CURRENT_PROJECT_VERSION) 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | 22 | 23 | -------------------------------------------------------------------------------- /Source/SocketRocket/Internal/ARTSRConstants.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2016-present, Facebook, Inc. 3 | // All rights reserved. 4 | // 5 | // This source code is licensed under the BSD-style license found in the 6 | // LICENSE file in the root directory of this source tree. An additional grant 7 | // of patent rights can be found in the PATENTS file in the same directory. 8 | // 9 | 10 | #import 11 | 12 | typedef NS_ENUM(uint8_t, ARTSROpCode) 13 | { 14 | ARTSROpCodeTextFrame = 0x1, 15 | ARTSROpCodeBinaryFrame = 0x2, 16 | // 3-7 reserved. 17 | ARTSROpCodeConnectionClose = 0x8, 18 | ARTSROpCodePing = 0x9, 19 | ARTSROpCodePong = 0xA, 20 | // B-F reserved. 21 | }; 22 | 23 | /** 24 | Default buffer size that is used for reading/writing to streams. 25 | */ 26 | extern size_t ARTSRDefaultBufferSize(void); 27 | -------------------------------------------------------------------------------- /Source/ARTRealtimeTransportFactory.m: -------------------------------------------------------------------------------- 1 | #import "ARTRealtimeTransportFactory.h" 2 | #import "ARTWebSocketTransport+Private.h" 3 | #import "ARTWebSocketFactory.h" 4 | 5 | @implementation ARTDefaultRealtimeTransportFactory 6 | 7 | - (id)transportWithRest:(ARTRestInternal *)rest options:(ARTClientOptions *)options resumeKey:(NSString *)resumeKey logger:(ARTInternalLog *)logger { 8 | const id webSocketFactory = [[ARTDefaultWebSocketFactory alloc] init]; 9 | return [[ARTWebSocketTransport alloc] initWithRest:rest 10 | options:options 11 | resumeKey:resumeKey 12 | logger:logger 13 | webSocketFactory:webSocketFactory]; 14 | } 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Source/SocketRocket/NSRunLoop+ARTSRWebSocket.m: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2012 Square Inc. 3 | // Portions Copyright (c) 2016-present, Facebook, Inc. 4 | // 5 | // All rights reserved. 6 | // 7 | // This source code is licensed under the BSD-style license found in the 8 | // LICENSE file in the root directory of this source tree. An additional grant 9 | // of patent rights can be found in the PATENTS file in the same directory. 10 | // 11 | 12 | #import "NSRunLoop+ARTSRWebSocket.h" 13 | #import "NSRunLoop+ARTSRWebSocketPrivate.h" 14 | 15 | #import "ARTSRRunLoopThread.h" 16 | 17 | // Required for object file to always be linked. 18 | void import_NSRunLoop_ARTSRWebSocket(void) { } 19 | 20 | @implementation NSRunLoop (ARTSRWebSocket) 21 | 22 | + (NSRunLoop *)ARTSR_networkRunLoop 23 | { 24 | return [ARTSRRunLoopThread sharedThread].runLoop; 25 | } 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /Examples/Tests/TestsTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /Source/ARTDevicePushDetails.m: -------------------------------------------------------------------------------- 1 | #import "ARTPush.h" 2 | #import "ARTDevicePushDetails.h" 3 | #import "ARTDevicePushDetails+Private.h" 4 | 5 | @implementation ARTDevicePushDetails 6 | 7 | - (instancetype)init { 8 | if (self = [super init]) { 9 | _recipient = [[NSMutableDictionary alloc] init]; 10 | } 11 | return self; 12 | } 13 | 14 | - (id)copyWithZone:(NSZone *)zone { 15 | ARTDevicePushDetails *push = [[[self class] allocWithZone:zone] init]; 16 | 17 | push.recipient = [self.recipient copy]; 18 | push.state = self.state; 19 | push.errorReason = [self.errorReason copy]; 20 | 21 | return push; 22 | } 23 | 24 | - (NSString *)description { 25 | return [NSString stringWithFormat:@"%@ - \n\t recipient: %@; \n\t state: %@; \n\t errorReason: %@;", [super description], self.recipient, self.state, self.errorReason]; 26 | } 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /Source/SocketRocket/Internal/Utilities/ARTSRMutex.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2016-present, Facebook, Inc. 3 | // All rights reserved. 4 | // 5 | // This source code is licensed under the BSD-style license found in the 6 | // LICENSE file in the root directory of this source tree. An additional grant 7 | // of patent rights can be found in the PATENTS file in the same directory. 8 | // 9 | 10 | #import 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | typedef __attribute__((capability("mutex"))) pthread_mutex_t *ARTSRMutex; 15 | 16 | extern ARTSRMutex ARTSRMutexInitRecursive(void); 17 | extern void ARTSRMutexDestroy(ARTSRMutex mutex); 18 | 19 | extern void ARTSRMutexLock(ARTSRMutex mutex) __attribute__((acquire_capability(mutex))); 20 | extern void ARTSRMutexUnlock(ARTSRMutex mutex) __attribute__((release_capability(mutex))); 21 | 22 | NS_ASSUME_NONNULL_END 23 | -------------------------------------------------------------------------------- /Source/include/Ably/ARTWrapperSDKProxyOptions.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | NS_ASSUME_NONNULL_BEGIN 4 | 5 | NS_SWIFT_SENDABLE 6 | 7 | /** 8 | * A set of options for controlling the creation of an `ARTWrapperSDKProxyRealtime` object. 9 | */ 10 | @interface ARTWrapperSDKProxyOptions: NSObject 11 | 12 | /** 13 | * A set of additional entries for the Ably agent header and the `agent` realtime channel param. 14 | * 15 | * If an agent does not have a version, represent this by using the `ARTClientInformationAgentNotVersioned` pointer as the version. 16 | */ 17 | @property (nonatomic, readonly, nullable) NSDictionary *agents; 18 | 19 | - (instancetype)initWithAgents:(nullable NSDictionary *)agents NS_DESIGNATED_INITIALIZER; 20 | - (instancetype)init NS_UNAVAILABLE; 21 | 22 | @end 23 | 24 | NS_ASSUME_NONNULL_END 25 | -------------------------------------------------------------------------------- /Test/AblyTests/Test Utilities/MockRetryDelayCalculator.swift: -------------------------------------------------------------------------------- 1 | import Ably.Private 2 | 3 | /// A mock implementation of `RetryDelayCalculator`, whose `delay(forRetryNumber:)` method returns values from a provided array. 4 | class MockRetryDelayCalculator: RetryDelayCalculator { 5 | private let delays: [TimeInterval] 6 | 7 | /// Creates a retry delay calculator whose `delay(forRetryNumber:)` method returns values from a provided sequence. 8 | /// 9 | /// - Parameters: 10 | /// - delays: A sequence of time intervals. The created retry delay calculator's `delay(forRetryNumber:)` method will return the `(retryNumber - 1)`-th element of this array. 11 | init(delays: [TimeInterval]) { 12 | self.delays = delays 13 | } 14 | 15 | func delay(forRetryNumber retryNumber: Int) -> TimeInterval { 16 | delays[retryNumber - 1] 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTMessage+Private.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | NS_ASSUME_NONNULL_BEGIN 4 | 5 | @interface ARTMessage () 6 | 7 | /** 8 | * Whether the `action` property has been set by the internals of the SDK. 9 | * 10 | * This property defaults to `NO`, indicating that the `action` property is either the default value or has been set by the user. As described in the documentation for `action`, this means that the SDK should ignore the value of this property. In particular, it should not populate this property when sending this message over the wire. 11 | * 12 | * - Note: If we had a separate `WireMessage` type instead of using `ARTMessage` as both our internal and external representation of a message, then we wouldn't need this mechanism. But we don't. 13 | */ 14 | @property (nonatomic) BOOL actionIsInternallySet; 15 | 16 | @end 17 | 18 | NS_ASSUME_NONNULL_END 19 | -------------------------------------------------------------------------------- /Test/AblyTests/Codables/CryptoData.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | struct CryptoData: Codable { 4 | let algorithm: String 5 | let mode: String 6 | let keylength: Int 7 | let key: String 8 | let iv: String 9 | let items: [Item] 10 | } 11 | 12 | /** 13 | Item 14 | */ 15 | extension CryptoData { 16 | struct Item: Codable { 17 | let encoded: Encoded 18 | let encrypted: Encrypted 19 | let msgpack: String 20 | } 21 | } 22 | 23 | /** 24 | Encrypted 25 | */ 26 | extension CryptoData.Item { 27 | struct Encrypted: Codable { 28 | let name: String 29 | let data: String 30 | let encoding: String 31 | } 32 | } 33 | 34 | /** 35 | Encoded 36 | */ 37 | extension CryptoData.Item { 38 | struct Encoded: Codable { 39 | let name: String 40 | let data: String 41 | let encoding: String? 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Source/include/Ably/ARTWrapperSDKProxyRealtimeChannels.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @class ARTWrapperSDKProxyRealtimeChannel; 5 | 6 | NS_ASSUME_NONNULL_BEGIN 7 | 8 | /** 9 | * An object which wraps an instance of `ARTRealtimeChannels` 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. 10 | * 11 | * - Important: This class should only be used by Ably-authored SDKs. 12 | */ 13 | NS_SWIFT_SENDABLE 14 | @interface ARTWrapperSDKProxyRealtimeChannels : NSObject 15 | 16 | - (instancetype)init NS_UNAVAILABLE; 17 | 18 | - (ARTWrapperSDKProxyRealtimeChannel *)get:(NSString *)name; 19 | - (ARTWrapperSDKProxyRealtimeChannel *)get:(NSString *)name options:(ARTRealtimeChannelOptions *)options; 20 | 21 | @end 22 | 23 | NS_ASSUME_NONNULL_END 24 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTQueuedMessage.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @class ARTProtocolMessage; 5 | 6 | NS_ASSUME_NONNULL_BEGIN 7 | 8 | /// :nodoc: 9 | @interface ARTQueuedMessage : NSObject 10 | 11 | @property (readonly, nonatomic) ARTProtocolMessage *msg; 12 | @property (readonly, nonatomic) NSMutableArray *sentCallbacks; 13 | @property (readonly, nonatomic) NSMutableArray *ackCallbacks; 14 | 15 | - (instancetype)initWithProtocolMessage:(ARTProtocolMessage *)msg sentCallback:(nullable ARTCallback)sentCallback ackCallback:(nullable ARTStatusCallback)ackCallback; 16 | 17 | - (BOOL)mergeFrom:(ARTProtocolMessage *)msg maxSize:(NSInteger)maxSize sentCallback:(nullable ARTCallback)sentCallback ackCallback:(nullable ARTStatusCallback)ackCallback; 18 | 19 | - (ARTCallback)sentCallback; 20 | - (ARTStatusCallback)ackCallback; 21 | 22 | @end 23 | 24 | NS_ASSUME_NONNULL_END 25 | -------------------------------------------------------------------------------- /Source/ARTPluginDecodingContext.m: -------------------------------------------------------------------------------- 1 | #ifdef ABLY_SUPPORTS_PLUGINS 2 | 3 | #import "ARTPluginDecodingContext.h" 4 | 5 | @implementation ARTPluginDecodingContext 6 | 7 | @synthesize parentID = _parentID; 8 | @synthesize parentConnectionID = _parentConnectionID; 9 | @synthesize parentTimestamp = _parentTimestamp; 10 | @synthesize indexInParent = _indexInParent; 11 | 12 | - (instancetype)initWithParentID:(NSString *)parentID 13 | parentConnectionID:(NSString *)parentConnectionID 14 | parentTimestamp:(NSDate *)parentTimestamp 15 | indexInParent:(NSInteger)indexInParent { 16 | self = [super init]; 17 | if (self) { 18 | _parentID = [parentID copy]; 19 | _parentConnectionID = [parentConnectionID copy]; 20 | _parentTimestamp = [parentTimestamp copy]; 21 | _indexInParent = indexInParent; 22 | } 23 | return self; 24 | } 25 | 26 | @end 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /Source/include/Ably/ARTDevicePushDetails.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @class ARTErrorInfo; 4 | 5 | NS_ASSUME_NONNULL_BEGIN 6 | 7 | /** 8 | * Contains the details of the push registration of a device. 9 | */ 10 | NS_SWIFT_SENDABLE 11 | @interface ARTDevicePushDetails : NSObject 12 | 13 | /** 14 | * A JSON object of key-value pairs that contains of the push transport and address. 15 | */ 16 | @property (nonatomic, readonly) NSMutableDictionary *recipient; 17 | 18 | /** 19 | * The current state of the push registration. 20 | */ 21 | @property (nullable, nonatomic, readonly) NSString *state; 22 | 23 | /** 24 | * An `ARTErrorInfo` object describing the most recent error when the `state` is `Failing` or `Failed`. 25 | */ 26 | @property (nullable, nonatomic, readonly) ARTErrorInfo *errorReason; 27 | 28 | /// :nodoc: 29 | - (instancetype)init; 30 | 31 | @end 32 | 33 | NS_ASSUME_NONNULL_END 34 | -------------------------------------------------------------------------------- /Source/SocketRocket/Internal/Utilities/ARTSRRandom.m: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2016-present, Facebook, Inc. 3 | // All rights reserved. 4 | // 5 | // This source code is licensed under the BSD-style license found in the 6 | // LICENSE file in the root directory of this source tree. An additional grant 7 | // of patent rights can be found in the PATENTS file in the same directory. 8 | // 9 | 10 | #import "ARTSRRandom.h" 11 | 12 | #import 13 | 14 | NS_ASSUME_NONNULL_BEGIN 15 | 16 | NSData *ARTSRRandomData(NSUInteger length) 17 | { 18 | NSMutableData *data = [NSMutableData dataWithLength:length]; 19 | int result = SecRandomCopyBytes(kSecRandomDefault, data.length, data.mutableBytes); 20 | if (result != 0) { 21 | [NSException raise:NSInternalInconsistencyException format:@"Failed to generate random bytes with OSStatus: %d", result]; 22 | } 23 | return data; 24 | } 25 | 26 | NS_ASSUME_NONNULL_END 27 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTJitterCoefficientGenerator.h: -------------------------------------------------------------------------------- 1 | @import Foundation; 2 | 3 | NS_ASSUME_NONNULL_BEGIN 4 | 5 | /** 6 | An object which generates the random "jitter coefficient" used to determine when the library will next retry an operation. 7 | */ 8 | NS_SWIFT_NAME(JitterCoefficientGenerator) 9 | @protocol ARTJitterCoefficientGenerator 10 | 11 | /** 12 | Generates a random number (approximately uniformly distributed) in the range [0.8, 1], as required by RTB1b. 13 | 14 | Test implementations of `ARTJitterCoefficientGenerator` may return a non-random number. 15 | */ 16 | - (double)generateJitterCoefficient; 17 | 18 | @end 19 | 20 | /** 21 | The implementation of `ARTJitterCoefficientGenerator` that should be used in non-test code. 22 | */ 23 | NS_SWIFT_NAME(DefaultJitterCoefficientGenerator) 24 | @interface ARTDefaultJitterCoefficientGenerator: NSObject 25 | @end 26 | 27 | NS_ASSUME_NONNULL_END 28 | -------------------------------------------------------------------------------- /Source/include/Ably/ARTMessageOperation.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import "ARTStringifiable.h" 4 | 5 | NS_ASSUME_NONNULL_BEGIN 6 | 7 | /** 8 | * Contains operation metadata for message updates. 9 | */ 10 | NS_SWIFT_SENDABLE 11 | @interface ARTMessageOperation : NSObject 12 | 13 | /// The client ID associated with this operation. 14 | @property (nullable, readonly, nonatomic) NSString *clientId; 15 | 16 | /// A description of the operation performed. 17 | @property (nullable, readonly, nonatomic) NSString *descriptionText; 18 | 19 | /// Metadata associated with the operation. 20 | @property (nullable, readonly, nonatomic) NSDictionary *metadata; 21 | 22 | - (instancetype)initWithClientId:(nullable NSString *)clientId descriptionText:(nullable NSString *)descriptionText metadata:(nullable NSDictionary *)metadata; 23 | 24 | @end 25 | 26 | NS_ASSUME_NONNULL_END 27 | -------------------------------------------------------------------------------- /Source/Info-macOS.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | $(CURRENT_PROJECT_VERSION) 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | NSHumanReadableCopyright 22 | Copyright © 2018 Ably. All rights reserved. 23 | 24 | 25 | -------------------------------------------------------------------------------- /Source/SocketRocket/Internal/Utilities/ARTSRHTTPConnectMessage.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2016-present, Facebook, Inc. 3 | // All rights reserved. 4 | // 5 | // This source code is licensed under the BSD-style license found in the 6 | // LICENSE file in the root directory of this source tree. An additional grant 7 | // of patent rights can be found in the PATENTS file in the same directory. 8 | // 9 | 10 | #import 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | extern CFHTTPMessageRef ARTSRHTTPConnectMessageCreate(NSURLRequest *request, 15 | NSString *securityKey, 16 | uint8_t webSocketProtocolVersion, 17 | NSArray *_Nullable cookies, 18 | NSArray *_Nullable requestedProtocols); 19 | 20 | NS_ASSUME_NONNULL_END 21 | -------------------------------------------------------------------------------- /Source/include/Ably/ARTMessageVersion.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | NS_ASSUME_NONNULL_BEGIN 5 | 6 | /** 7 | * Contains version information for a message, including operation metadata. 8 | */ 9 | @interface ARTMessageVersion : NSObject 10 | 11 | /// The serial of the message version. 12 | @property (nullable, readwrite, nonatomic) NSString *serial; 13 | 14 | /// The timestamp of the message version. 15 | @property (nullable, readwrite, nonatomic) NSDate *timestamp; 16 | 17 | /// The client ID associated with this version. 18 | @property (nullable, readwrite, nonatomic) NSString *clientId; 19 | 20 | /// A description of the operation performed. 21 | @property (nullable, readwrite, nonatomic) NSString *descriptionText; 22 | 23 | /// Metadata associated with the operation. 24 | @property (nullable, readwrite, nonatomic) NSDictionary *metadata; 25 | 26 | @end 27 | 28 | NS_ASSUME_NONNULL_END 29 | -------------------------------------------------------------------------------- /Source/include/Ably/ARTWrapperSDKProxyPushAdmin.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @class ARTWrapperSDKProxyPushDeviceRegistrations; 5 | @class ARTWrapperSDKProxyPushChannelSubscriptions; 6 | 7 | NS_ASSUME_NONNULL_BEGIN 8 | 9 | /** 10 | * 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. 11 | * 12 | * - Important: This class should only be used by Ably-authored SDKs. 13 | */ 14 | NS_SWIFT_SENDABLE 15 | @interface ARTWrapperSDKProxyPushAdmin : NSObject 16 | 17 | - (instancetype)init NS_UNAVAILABLE; 18 | 19 | @property (nonatomic, readonly) ARTWrapperSDKProxyPushDeviceRegistrations *deviceRegistrations; 20 | @property (nonatomic, readonly) ARTWrapperSDKProxyPushChannelSubscriptions *channelSubscriptions; 21 | 22 | @end 23 | 24 | NS_ASSUME_NONNULL_END 25 | -------------------------------------------------------------------------------- /Examples/SPM/Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.3 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | import Darwin.C 6 | 7 | let package = Package( 8 | name: "SPMIntegration", 9 | platforms: [ 10 | .iOS(.v9), 11 | .macOS(.v10_11) 12 | ], 13 | dependencies: [ 14 | .package(path: "../../") 15 | ], 16 | targets: [ 17 | .target( 18 | name: "SPMIntegration", 19 | dependencies: [ 20 | .product(name: "Ably", package: "ably-cocoa") 21 | ], 22 | swiftSettings: [ 23 | .unsafeFlags(["-warnings-as-errors"]) 24 | ]), 25 | .testTarget( 26 | name: "SPMTests", 27 | dependencies: ["SPMIntegration"], 28 | swiftSettings: [ 29 | .unsafeFlags(["-warnings-as-errors"]) 30 | ]), 31 | ] 32 | ) 33 | -------------------------------------------------------------------------------- /Source/ARTFallbackHosts.m: -------------------------------------------------------------------------------- 1 | #import "ARTFallbackHosts.h" 2 | 3 | #import "ARTDefault+Private.h" 4 | #import "ARTClientOptions+Private.h" 5 | 6 | @implementation ARTFallbackHosts 7 | 8 | + (nullable NSArray *)hostsFromOptions:(ARTClientOptions *)options { 9 | if (options.fallbackHosts) { 10 | return options.fallbackHosts; 11 | } 12 | 13 | #pragma clang diagnostic push 14 | #pragma clang diagnostic ignored "-Wdeprecated-declarations" 15 | if (options.fallbackHostsUseDefault) { 16 | return [ARTDefault fallbackHosts]; 17 | } 18 | #pragma clang diagnostic pop 19 | 20 | if (options.hasEnvironmentDifferentThanProduction) { 21 | return [ARTDefault fallbackHostsWithEnvironment:options.environment]; 22 | } 23 | if (options.hasCustomRestHost || options.hasCustomRealtimeHost || options.hasCustomPort || options.hasCustomTlsPort) { 24 | return nil; 25 | } 26 | return [ARTDefault fallbackHosts]; 27 | } 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /Docs/Main.md: -------------------------------------------------------------------------------- 1 | # Ably Cocoa Client Library SDK API Reference 2 | 3 | The Cocoa Client Library SDK supports a realtime and a REST interface. The Cocoa API references are generated from the [Ably Cocoa Client Library SDK source code](https://github.com/ably/ably-cocoa/) using [Jazzy](https://github.com/realm/jazzy) and structured by classes. 4 | 5 | The realtime interface enables a client to maintain a persistent connection to Ably and publish, subscribe and be present on channels. The REST interface is stateless and typically implemented server-side. It is used to make requests such as retrieving statistics, token authentication and publishing to a channel. 6 | 7 | View the [Ably docs](https://ably.com/docs/) for conceptual information on using Ably, and for API references featuring all languages. The combined [API references](https://ably.com/docs/api/) are organized by features and split between the [realtime](https://ably.com/docs/api/realtime-sdk) and [REST](https://ably.com/docs/api/rest-sdk) interfaces. -------------------------------------------------------------------------------- /Source/SocketRocket/Internal/Utilities/ARTSRError.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2016-present, Facebook, Inc. 3 | // All rights reserved. 4 | // 5 | // This source code is licensed under the BSD-style license found in the 6 | // LICENSE file in the root directory of this source tree. An additional grant 7 | // of patent rights can be found in the PATENTS file in the same directory. 8 | // 9 | 10 | #import 11 | 12 | #import "ARTSRWebSocket.h" 13 | 14 | NS_ASSUME_NONNULL_BEGIN 15 | 16 | extern NSError *ARTSRErrorWithDomainCodeDescription(NSString *domain, NSInteger code, NSString *description); 17 | extern NSError *ARTSRErrorWithCodeDescription(NSInteger code, NSString *description); 18 | extern NSError *ARTSRErrorWithCodeDescriptionUnderlyingError(NSInteger code, NSString *description, NSError *underlyingError); 19 | 20 | extern NSError *ARTSRHTTPErrorWithCodeDescription(NSInteger httpCode, NSInteger errorCode, NSString *description); 21 | 22 | NS_ASSUME_NONNULL_END 23 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTErrorChecker.h: -------------------------------------------------------------------------------- 1 | @import Foundation; 2 | 3 | @class ARTErrorInfo; 4 | 5 | NS_ASSUME_NONNULL_BEGIN 6 | 7 | /** 8 | Checks an `ARTErrorInfo` to see whether it falls into a given class of errors defined by the client library specification. 9 | 10 | In addition to putting shared error logic in a common place, it allows us to provide a mock instance when testing components that need to perform error checking, without having to worry about creating representative errors in our test cases. 11 | */ 12 | NS_SWIFT_NAME(ErrorChecker) 13 | @protocol ARTErrorChecker 14 | 15 | /** 16 | Returns whether the given error is a token error, as defined by RTH15h1. 17 | */ 18 | - (BOOL)isTokenError:(ARTErrorInfo *)errorInfo; 19 | 20 | @end 21 | 22 | /** 23 | The implementation of `ARTErrorChecker` that should be used in non-test code. 24 | */ 25 | NS_SWIFT_NAME(DefaultErrorChecker) 26 | @interface ARTDefaultErrorChecker: NSObject 27 | @end 28 | 29 | NS_ASSUME_NONNULL_END 30 | -------------------------------------------------------------------------------- /Source/include/Ably/ARTWrapperSDKProxyRealtime.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @class ARTConnection; 5 | @class ARTWrapperSDKProxyRealtimeChannels; 6 | @class ARTWrapperSDKProxyPush; 7 | @class ARTAuth; 8 | 9 | NS_ASSUME_NONNULL_BEGIN 10 | 11 | /** 12 | * An object which wraps an instance of `ARTRealtime` 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. 13 | * 14 | * - Important: This class should only be used by Ably-authored SDKs. 15 | */ 16 | NS_SWIFT_SENDABLE 17 | @interface ARTWrapperSDKProxyRealtime : NSObject 18 | 19 | - (instancetype)init NS_UNAVAILABLE; 20 | 21 | @property (readonly) ARTConnection *connection; 22 | @property (readonly) ARTWrapperSDKProxyRealtimeChannels *channels; 23 | @property (readonly) ARTWrapperSDKProxyPush *push; 24 | @property (readonly) ARTAuth *auth; 25 | 26 | @end 27 | 28 | NS_ASSUME_NONNULL_END 29 | -------------------------------------------------------------------------------- /Scripts/carthage-with-workaround-for-issue-3019.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # copied from: 4 | # https://github.com/Carthage/Carthage/issues/3019#issuecomment-665136323 5 | 6 | set -euo pipefail 7 | 8 | xcconfig=$(mktemp /tmp/static.xcconfig.XXXXXX) 9 | trap 'rm -f "$xcconfig"' INT TERM HUP EXIT 10 | 11 | # For Xcode 16 make sure EXCLUDED_ARCHS is set to arm architectures otherwise 12 | # the build will fail on lipo due to duplicate architectures. 13 | echo 'EXCLUDED_ARCHS__EFFECTIVE_PLATFORM_SUFFIX_simulator__NATIVE_ARCH_64_BIT_x86_64__XCODE_1600 = arm64 arm64e armv7 armv7s armv6 armv8' >> $xcconfig 14 | echo 'EXCLUDED_ARCHS__EFFECTIVE_PLATFORM_SUFFIX_simulator__NATIVE_ARCH_64_BIT_arm64__XCODE_1600 = arm64 arm64e armv7 armv7s armv6 armv8' >> $xcconfig 15 | echo 'EXCLUDED_ARCHS = $(inherited) $(EXCLUDED_ARCHS__EFFECTIVE_PLATFORM_SUFFIX_$(EFFECTIVE_PLATFORM_SUFFIX)__NATIVE_ARCH_64_BIT_$(NATIVE_ARCH_64_BIT)__XCODE_$(XCODE_VERSION_MAJOR))' >> $xcconfig 16 | 17 | export XCODE_XCCONFIG_FILE="$xcconfig" 18 | carthage "$@" 19 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTRealtimeAnnotations+Private.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import "ARTRealtimeChannel+Private.h" 3 | 4 | NS_ASSUME_NONNULL_BEGIN 5 | 6 | @interface ARTRealtimeAnnotationsInternal : NSObject 7 | 8 | @property (readonly, nonatomic) ARTEventEmitter *eventEmitter; 9 | @property (readonly, weak, nonatomic) ARTRealtimeInternal *realtime; // weak because realtime owns self 10 | 11 | - (instancetype)initWithChannel:(ARTRealtimeChannelInternal *)channel logger:(ARTInternalLog *)logger; 12 | 13 | - (void)onMessage:(ARTProtocolMessage *)message; 14 | 15 | @property (nonatomic) dispatch_queue_t queue; 16 | 17 | @end 18 | 19 | @interface ARTRealtimeAnnotations () 20 | 21 | @property (nonatomic, readonly) ARTRealtimeAnnotationsInternal *internal; 22 | 23 | - (instancetype)initWithInternal:(ARTRealtimeAnnotationsInternal *)internal queuedDealloc:(ARTQueuedDealloc *)dealloc; 24 | 25 | @end 26 | 27 | NS_ASSUME_NONNULL_END 28 | -------------------------------------------------------------------------------- /Source/SocketRocket/Internal/Proxy/ARTSRProxyConnect.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2016-present, Facebook, Inc. 3 | // All rights reserved. 4 | // 5 | // This source code is licensed under the BSD-style license found in the 6 | // LICENSE file in the root directory of this source tree. An additional grant 7 | // of patent rights can be found in the PATENTS file in the same directory. 8 | // 9 | 10 | #import 11 | 12 | @class ARTInternalLog; 13 | 14 | NS_ASSUME_NONNULL_BEGIN 15 | 16 | typedef void(^ARTSRProxyConnectCompletion)(NSError *_Nullable error, 17 | NSInputStream *_Nullable readStream, 18 | NSOutputStream *_Nullable writeStream); 19 | 20 | @interface ARTSRProxyConnect : NSObject 21 | 22 | - (instancetype)initWithURL:(NSURL *)url logger:(nullable ARTInternalLog *)logger; 23 | 24 | - (void)openNetworkStreamWithCompletion:(ARTSRProxyConnectCompletion)completion; 25 | 26 | @end 27 | 28 | NS_ASSUME_NONNULL_END 29 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTBackoffRetryDelayCalculator.h: -------------------------------------------------------------------------------- 1 | @import Foundation; 2 | #import "ARTRetryDelayCalculator.h" 3 | 4 | @protocol ARTJitterCoefficientGenerator; 5 | 6 | NS_ASSUME_NONNULL_BEGIN 7 | 8 | /** 9 | An implementation of `ARTRetryDelayCalculator` which uses the incremental backoff and jitter rules of RTB1. 10 | */ 11 | NS_SWIFT_NAME(BackoffRetryDelayCalculator) 12 | @interface ARTBackoffRetryDelayCalculator: NSObject 13 | 14 | - (instancetype)init NS_UNAVAILABLE; 15 | 16 | /** 17 | Creates an instance of `ARTRetryDelayCalculator`. 18 | 19 | - Parameters: 20 | - initialRetryTimeout: The initial retry timeout, as defined by RTB1. 21 | - jitterCoefficientGenerator: An object to use for generating the jitter coefficients. 22 | */ 23 | - (instancetype)initWithInitialRetryTimeout:(NSTimeInterval)initialRetryTimeout 24 | jitterCoefficientGenerator:(id)jitterCoefficientGenerator; 25 | 26 | @end 27 | 28 | NS_ASSUME_NONNULL_END 29 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTRealtimeTransportFactory.h: -------------------------------------------------------------------------------- 1 | @import Foundation; 2 | 3 | @class ARTRestInternal; 4 | @class ARTClientOptions; 5 | @class ARTInternalLog; 6 | @protocol ARTRealtimeTransport; 7 | 8 | NS_ASSUME_NONNULL_BEGIN 9 | 10 | /** 11 | A factory for creating an `ARTRealtimeTransport` instance. 12 | */ 13 | NS_SWIFT_NAME(RealtimeTransportFactory) 14 | @protocol ARTRealtimeTransportFactory 15 | 16 | - (id)transportWithRest:(ARTRestInternal *)rest 17 | options:(ARTClientOptions *)options 18 | resumeKey:(nullable NSString *)resumeKey 19 | logger:(ARTInternalLog *)logger; 20 | 21 | @end 22 | 23 | /** 24 | The implementation of `ARTRealtimeTransportFactory` that should be used in non-test code. 25 | */ 26 | NS_SWIFT_NAME(DefaultRealtimeTransportFactory) 27 | @interface ARTDefaultRealtimeTransportFactory: NSObject 28 | @end 29 | 30 | NS_ASSUME_NONNULL_END 31 | -------------------------------------------------------------------------------- /Source/ARTNSMutableURLRequest+ARTUtils.m: -------------------------------------------------------------------------------- 1 | #import "ARTNSMutableURLRequest+ARTUtils.h" 2 | 3 | @implementation NSMutableURLRequest (ARTUtils) 4 | 5 | - (void)appendQueryItem:(NSURLQueryItem *)item { 6 | NSURLComponents *components = [NSURLComponents componentsWithURL:self.URL resolvingAgainstBaseURL:YES]; 7 | if(components == nil) { 8 | return; 9 | } 10 | 11 | NSMutableArray *mutableQueryItems = [NSMutableArray arrayWithArray:components.queryItems]; 12 | [mutableQueryItems addObject:item]; 13 | components.queryItems = mutableQueryItems; 14 | 15 | NSURL *modifiedURL = components.URL; 16 | if (modifiedURL != nil) { 17 | self.URL = modifiedURL; 18 | } 19 | } 20 | 21 | - (void)replaceHostWith:(NSString *)host { 22 | NSURLComponents *components = [NSURLComponents componentsWithURL:self.URL resolvingAgainstBaseURL:YES]; 23 | components.host = host; 24 | 25 | if(components != nil) { 26 | self.URL = components.URL; 27 | } 28 | } 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /Test/AblyTests/Test Utilities/Test.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | /** 4 | Represents an execution of a test case method. 5 | */ 6 | struct Test { 7 | var id = UUID() 8 | private var function: StaticString 9 | 10 | init(function: StaticString = #function) { 11 | self.function = function 12 | NSLog("Created test \(id) for function \(function)") 13 | } 14 | 15 | func uniqueChannelName(prefix: String = "", 16 | timestamp: TimeInterval = Date.timeIntervalSinceReferenceDate) -> String { 17 | let platform: String 18 | #if targetEnvironment(macCatalyst) 19 | platform = "macCatalyst" 20 | #elseif os(OSX) 21 | platform = "OSX" 22 | #elseif os(iOS) 23 | platform = "iOS" 24 | #elseif os(tvOS) 25 | platform = "tvOS" 26 | #elseif os(watchOS) 27 | platform = "watchOS" 28 | #else 29 | platform = "Unknown" 30 | #endif 31 | return "\(prefix)-\(platform)-\(id)-\(timestamp)-\(NSUUID().uuidString)" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Source/PrivacyInfo.xcprivacy: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSPrivacyCollectedDataTypes 6 | 7 | 8 | NSPrivacyCollectedDataType 9 | NSPrivacyCollectedDataTypeDeviceID 10 | NSPrivacyCollectedDataTypeLinked 11 | 12 | NSPrivacyCollectedDataTypeTracking 13 | 14 | NSPrivacyCollectedDataTypePurposes 15 | 16 | NSPrivacyCollectedDataTypePurposeAppFunctionality 17 | 18 | 19 | 20 | NSPrivacyAccessedAPITypes 21 | 22 | 23 | NSPrivacyAccessedAPIType 24 | NSPrivacyAccessedAPICategoryUserDefaults 25 | NSPrivacyAccessedAPITypeReasons 26 | 27 | CA92.1 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /Test/AblyTests/Tests/ContinuousClockTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import Ably.Private 3 | 4 | class ContinuousClockTests: XCTestCase { 5 | func test_isAfter() { 6 | let clock = ARTContinuousClock() 7 | 8 | let preSleepNow = clock.now() 9 | // Sleep for 0.25s 10 | usleep(UInt32(0.25 * Double(USEC_PER_SEC))) 11 | let postSleepNow = clock.now() 12 | 13 | XCTAssertTrue(postSleepNow.isAfter(preSleepNow)) 14 | } 15 | 16 | func test_advancedBy() { 17 | let clock = ARTContinuousClock() 18 | 19 | let preSleepNow = clock.now() 20 | let advancedByQuarterSecond = clock.addingDuration(0.25, to: preSleepNow) 21 | let advancedByOneSecond = clock.addingDuration(1, to: preSleepNow) 22 | 23 | // Sleep for 0.5s 24 | usleep(UInt32(0.5 * Double(USEC_PER_SEC))) 25 | 26 | let postSleepNow = clock.now() 27 | XCTAssertFalse(advancedByQuarterSecond.isAfter(postSleepNow)) 28 | XCTAssertTrue(advancedByOneSecond.isAfter(postSleepNow)) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTRetryDelayCalculator.h: -------------------------------------------------------------------------------- 1 | @import Foundation; 2 | 3 | NS_ASSUME_NONNULL_BEGIN 4 | 5 | /** 6 | Consider an operation which can fail. If we attempt to perform the operation and it fails, we may wish to start performing a sequence of retries, until success or some other termination condition is achieved. An `ARTRetryDelayCalculator` describes the amount of time that we wish to wait before performing each retry in this sequence. 7 | */ 8 | NS_SWIFT_NAME(RetryDelayCalculator) 9 | @protocol ARTRetryDelayCalculator 10 | 11 | /** 12 | Returns the duration that should be waited before performing a retry of the operation. 13 | 14 | - Parameters: 15 | - retryNumber: The ordinal of the retry in the retry sequence, greater than or equal to 1. After the first attempt at the operation fails, the subsequent attempt is considered retry number 1. 16 | 17 | What constitutes the "first attempt" is for the caller to decide. 18 | */ 19 | - (NSTimeInterval)delayForRetryNumber:(NSInteger)retryNumber; 20 | 21 | @end 22 | 23 | NS_ASSUME_NONNULL_END 24 | -------------------------------------------------------------------------------- /Test/AblyTests/Test Utilities/StaticJitterCoefficients.swift: -------------------------------------------------------------------------------- 1 | /// An infinite sequence of `Double` values in the range `0.8 ... 1`, suitable to be used for the return values of a mock instance of `JitterCoefficientGenerator`. All iterations of all instances of `StaticJitterCoefficients` return the same sequence of numbers. 2 | struct StaticJitterCoefficients: Sequence { 3 | struct Iterator: IteratorProtocol { 4 | private let maxIndex = 10 5 | private var index = 0 // in range 0...maxIndex 6 | 7 | mutating func next() -> Double? { 8 | // Not a particularly thought-through implementation — just something that gives a non-monotonic sequence. 9 | 10 | let progress = Double(index) / Double(maxIndex) // in range 0...1 11 | index = (index + 1) % (maxIndex + 1) 12 | let direction = index.isMultiple(of: 2) ? 1 : -1 13 | return 0.9 + (Double(direction) * progress * 0.1) 14 | } 15 | } 16 | 17 | func makeIterator() -> Iterator { 18 | return Iterator() 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Source/SocketRocket/Internal/Utilities/ARTSRLog.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2016-present, Facebook, Inc. 3 | // All rights reserved. 4 | // 5 | // This source code is licensed under the BSD-style license found in the 6 | // LICENSE file in the root directory of this source tree. An additional grant 7 | // of patent rights can be found in the PATENTS file in the same directory. 8 | // 9 | 10 | #import 11 | #import "ARTInternalLog.h" 12 | 13 | NS_ASSUME_NONNULL_BEGIN 14 | 15 | // Uncomment this line to enable debug logging 16 | //#define ARTSR_DEBUG_LOG_ENABLED 17 | 18 | #define ARTSRErrorLog(logger, format, ...) ARTLogError(logger, @"%@", [NSString stringWithFormat:@"[SocketRocket] %@", [NSString stringWithFormat:format, ##__VA_ARGS__]]) 19 | 20 | #ifdef ARTSR_DEBUG_LOG_ENABLED 21 | #define ARTSRDebugLog(logger, format, ...) ARTLogDebug(logger, @"%@", [NSString stringWithFormat:@"[SocketRocket] %@", [NSString stringWithFormat:format, ##__VA_ARGS__]]) 22 | #else 23 | #define ARTSRDebugLog(logger, format, ...) 24 | #endif 25 | 26 | NS_ASSUME_NONNULL_END 27 | -------------------------------------------------------------------------------- /Source/include/Ably/ARTRestChannels.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import 4 | 5 | NS_ASSUME_NONNULL_BEGIN 6 | 7 | /// :nodoc: 8 | @protocol ARTRestChannelsProtocol 9 | 10 | // We copy this from the parent class and replace ChannelType by ARTRestChannel * because 11 | // Swift ignores Objective-C generics and thinks this is returning an id, failing to compile. 12 | // Thus, we can't make ARTRestChannels inherit from ARTChannels; we have to compose them instead. 13 | - (BOOL)exists:(NSString *)name; 14 | - (void)release:(NSString *)name; 15 | 16 | @end 17 | 18 | /// :nodoc: 19 | NS_SWIFT_SENDABLE 20 | @interface ARTRestChannels : NSObject 21 | 22 | - (ARTRestChannel *)get:(NSString *)name; 23 | - (ARTRestChannel *)get:(NSString *)name options:(ARTChannelOptions *)options; 24 | 25 | /** 26 | * Iterates through the existing channels. 27 | * 28 | * @return Each iteration returns an `ARTRestChannel` object. 29 | */ 30 | - (id)iterate; 31 | 32 | @end 33 | 34 | NS_ASSUME_NONNULL_END 35 | -------------------------------------------------------------------------------- /Source/SocketRocket/Internal/Utilities/ARTSRURLUtilities.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2016-present, Facebook, Inc. 3 | // All rights reserved. 4 | // 5 | // This source code is licensed under the BSD-style license found in the 6 | // LICENSE file in the root directory of this source tree. An additional grant 7 | // of patent rights can be found in the PATENTS file in the same directory. 8 | // 9 | 10 | #import 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | // The origin isn't really applicable for a native application. 15 | // So instead, just map ws -> http and wss -> https. 16 | extern NSString *ARTSRURLOrigin(NSURL *url); 17 | 18 | extern BOOL ARTSRURLRequiresSSL(NSURL *url); 19 | 20 | // Extracts `user` and `password` from url (if available) into `Basic base64(user:password)`. 21 | extern NSString *_Nullable ARTSRBasicAuthorizationHeaderFromURL(NSURL *url); 22 | 23 | // Returns a valid value for `NSStreamNetworkServiceType` or `nil`. 24 | extern NSString *_Nullable ARTSRStreamNetworkServiceTypeFromURLRequest(NSURLRequest *request); 25 | 26 | NS_ASSUME_NONNULL_END 27 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTPushAdmin+Private.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import "ARTPushDeviceRegistrations+Private.h" 3 | #import "ARTPushChannelSubscriptions+Private.h" 4 | #import "ARTQueuedDealloc.h" 5 | 6 | @class ARTRestInternal; 7 | 8 | NS_ASSUME_NONNULL_BEGIN 9 | 10 | @interface ARTPushAdminInternal : NSObject 11 | 12 | @property (nonatomic, readonly) ARTPushDeviceRegistrationsInternal *deviceRegistrations; 13 | @property (nonatomic, readonly) ARTPushChannelSubscriptionsInternal *channelSubscriptions; 14 | 15 | - (instancetype)initWithRest:(ARTRestInternal *)rest logger:(ARTInternalLog *)logger; 16 | 17 | - (void)publish:(ARTPushRecipient *)recipient data:(ARTJsonObject *)data wrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents callback:(nullable ARTCallback)callback; 18 | 19 | @end 20 | 21 | @interface ARTPushAdmin () 22 | 23 | @property (nonatomic, readonly) ARTPushAdminInternal *internal; 24 | 25 | - (instancetype)initWithInternal:(ARTPushAdminInternal *)internal queuedDealloc:(ARTQueuedDealloc *)dealloc; 26 | 27 | @end 28 | 29 | NS_ASSUME_NONNULL_END 30 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTChannel+Private.h: -------------------------------------------------------------------------------- 1 | #import "ARTChannel.h" 2 | #import "ARTDataEncoder.h" 3 | 4 | NS_ASSUME_NONNULL_BEGIN 5 | 6 | @class ARTRestInternal; 7 | @class ARTInternalLog; 8 | 9 | @interface ARTChannel() 10 | 11 | - (instancetype)initWithName:(NSString *)name andOptions:(ARTChannelOptions *)options rest:(ARTRestInternal *)rest logger:(ARTInternalLog *)logger; 12 | 13 | @property (readonly, nullable) ARTChannelOptions *options; 14 | 15 | @property (nonatomic, readonly) ARTDataEncoder *dataEncoder; 16 | 17 | /// Exposed so that `ARTPluginAPI` can allow plugins to log via this channel. 18 | @property (nonatomic, readonly) ARTInternalLog *logger; 19 | 20 | - (void)internalPostMessages:(id)data callback:(nullable ARTCallback)callback; 21 | - (BOOL)exceedMaxSize:(NSArray *)messages; 22 | 23 | - (nullable ARTChannelOptions *)options; 24 | - (nullable ARTChannelOptions *)options_nosync; 25 | - (void)setOptions:(ARTChannelOptions *_Nullable)options; 26 | - (void)setOptions_nosync:(ARTChannelOptions *_Nullable)options; 27 | 28 | @end 29 | 30 | NS_ASSUME_NONNULL_END 31 | -------------------------------------------------------------------------------- /Source/include/Ably/ARTChannelOptions.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #import 4 | #import 5 | 6 | NS_ASSUME_NONNULL_BEGIN 7 | 8 | /** 9 | * Passes additional properties to an `ARTRestChannel` object, such as encryption. 10 | */ 11 | @interface ARTChannelOptions : NSObject 12 | 13 | /** 14 | * Requests encryption for this channel when not `nil`, and specifies encryption-related parameters (such as algorithm, chaining mode, key length and key). See [an example](https://ably.com/docs/realtime/encryption#getting-started). 15 | */ 16 | @property (nonatomic, nullable) ARTCipherParams *cipher; 17 | 18 | /// :nodoc: TODO: docstring 19 | - (instancetype)initWithCipher:(id _Nullable)cipherParams; 20 | 21 | /** 22 | * Creates an options object using a key only. 23 | * 24 | * @param key A private key used to encrypt and decrypt payloads. 25 | * 26 | * @return An `ARTChannelOptions` object. 27 | */ 28 | - (instancetype)initWithCipherKey:(id)key; 29 | 30 | @end 31 | 32 | NS_ASSUME_NONNULL_END 33 | -------------------------------------------------------------------------------- /Source/ARTChannelStateChangeParams.m: -------------------------------------------------------------------------------- 1 | #import "ARTChannelStateChangeParams.h" 2 | 3 | @implementation ARTChannelStateChangeParams 4 | 5 | - (instancetype)initWithState:(ARTState)state { 6 | return [self initWithState:state errorInfo:nil storeErrorInfo:NO]; 7 | } 8 | 9 | - (instancetype)initWithState:(ARTState)state errorInfo:(ARTErrorInfo *)errorInfo { 10 | return [self initWithState:state errorInfo:errorInfo storeErrorInfo:YES]; 11 | } 12 | 13 | - (instancetype)initWithState:(ARTState)state errorInfo:(ARTErrorInfo *)errorInfo storeErrorInfo:(BOOL)storeErrorInfo { 14 | return [self initWithState:state errorInfo:errorInfo storeErrorInfo:storeErrorInfo retryAttempt:nil]; 15 | } 16 | 17 | - (instancetype)initWithState:(ARTState)state errorInfo:(ARTErrorInfo *)errorInfo storeErrorInfo:(BOOL)storeErrorInfo retryAttempt:(ARTRetryAttempt *)retryAttempt { 18 | if (self = [super init]) { 19 | _state = state; 20 | _errorInfo = errorInfo; 21 | _storeErrorInfo = storeErrorInfo; 22 | _retryAttempt = retryAttempt; 23 | } 24 | 25 | return self; 26 | } 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTChannels+Private.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @class ARTRestChannel; 4 | @class ARTChannelOptions; 5 | 6 | NS_ASSUME_NONNULL_BEGIN 7 | 8 | @protocol ARTChannelsDelegate 9 | 10 | - (id)makeChannel:(NSString *)channel options:(nullable ARTChannelOptions *)options; 11 | 12 | @end 13 | 14 | @interface ARTChannels () 15 | 16 | @property (nonatomic, readonly) NSMutableDictionary *channels; 17 | @property (readonly, getter=getNosyncIterable) id nosyncIterable; 18 | @property (nonatomic, readonly) NSString *prefix; 19 | 20 | - (NSString *)addPrefix:(NSString *)name; 21 | 22 | - (BOOL)_exists:(NSString *)name; 23 | - (ChannelType)_get:(NSString *)name; 24 | - (ChannelType)_getChannel:(NSString *)name options:(ARTChannelOptions * _Nullable)options addPrefix:(BOOL)addPrefix; 25 | - (void)_release:(NSString *)name; 26 | 27 | - (instancetype)initWithDelegate:(id)delegate dispatchQueue:(dispatch_queue_t)queue prefix:(nullable NSString *)prefix; 28 | 29 | @end 30 | 31 | NS_ASSUME_NONNULL_END 32 | -------------------------------------------------------------------------------- /Test/AblyTesting/MockInternalLogCore.swift: -------------------------------------------------------------------------------- 1 | import Ably.Private 2 | 3 | @objc(ARTMockInternalLogCore) 4 | public class MockInternalLogCore: NSObject, InternalLogCore { 5 | public var logLevel: ARTLogLevel = .none 6 | 7 | var lastReceivedLogMessageArguments: (message: String, level: ARTLogLevel, fileName: UnsafePointer, line: Int)? 8 | @objc public var lastReceivedLogMessageArgumentMessage: String? 9 | @objc public var lastReceivedLogMessageArgumentLevel: ARTLogLevel = .none 10 | @objc public var lastReceivedLogMessageArgumentFileName: UnsafePointer? 11 | @objc public var lastReceivedLogMessageArgumentLine: Int = -1 12 | 13 | public func log(_ message: String, with level: ARTLogLevel, file fileName: UnsafePointer, line: Int) { 14 | lastReceivedLogMessageArguments = (message: message, level: level, fileName: fileName, line: line) 15 | lastReceivedLogMessageArgumentMessage = message 16 | lastReceivedLogMessageArgumentLevel = level 17 | lastReceivedLogMessageArgumentFileName = fileName 18 | lastReceivedLogMessageArgumentLine = line 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Test/AblyTests/Tests/BackoffRetryDelayCalculatorTests.swift: -------------------------------------------------------------------------------- 1 | import Ably 2 | import XCTest 3 | 4 | class BackoffRetryDelayCalculatorTests: XCTestCase { 5 | func test_delay() { 6 | let initialRetryTimeout = 0.5 // arbitrarily chosen 7 | 8 | let jitterCoefficients = StaticJitterCoefficients() 9 | let mockJitterCoefficientGenerator = MockJitterCoefficientGenerator(coefficients: jitterCoefficients) 10 | 11 | let expectedDelays = AblyTests.expectedRetryDelays(forTimeout: initialRetryTimeout, jitterCoefficients: jitterCoefficients) 12 | 13 | let calculator = BackoffRetryDelayCalculator( 14 | initialRetryTimeout: initialRetryTimeout, 15 | jitterCoefficientGenerator: mockJitterCoefficientGenerator 16 | ) 17 | 18 | let calculatedDelays = (1...).lazy.map { calculator.delay(forRetryNumber: $0) } 19 | 20 | let sampleSize = 10 // arbitrarily chosen, large enough so that we see the initial values and then the constant tail 21 | XCTAssertEqual(Array(calculatedDelays.prefix(sampleSize)), Array(expectedDelays.prefix(sampleSize))) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Source/SocketRocket/Internal/Security/ARTSRPinningSecurityPolicy.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2016-present, Facebook, Inc. 3 | // All rights reserved. 4 | // 5 | // This source code is licensed under the BSD-style license found in the 6 | // LICENSE file in the root directory of this source tree. An additional grant 7 | // of patent rights can be found in the PATENTS file in the same directory. 8 | // 9 | 10 | #import 11 | 12 | #import "ARTSRSecurityPolicy.h" 13 | 14 | @class ARTInternalLog; 15 | 16 | NS_ASSUME_NONNULL_BEGIN 17 | 18 | /** 19 | * NOTE: While publicly, SocketRocket does not support configuring the security policy with pinned certificates, 20 | * it is still possible to manually construct a security policy of this class. If you do this, note that you may 21 | * be open to MitM attacks, and we will not support any issues you may have. Dive at your own risk. 22 | */ 23 | @interface ARTSRPinningSecurityPolicy : ARTSRSecurityPolicy 24 | 25 | - (instancetype)initWithCertificates:(NSArray *)pinnedCertificates logger:(nullable ARTInternalLog *)logger; 26 | 27 | @end 28 | 29 | NS_ASSUME_NONNULL_END 30 | -------------------------------------------------------------------------------- /Source/ARTStringifiable.m: -------------------------------------------------------------------------------- 1 | #import "ARTStringifiable.h" 2 | #import "ARTStringifiable+Private.h" 3 | 4 | @implementation ARTStringifiable 5 | 6 | - (instancetype)initWithString:(NSString *)value { 7 | self = [super init]; 8 | if (self) { 9 | _stringValue = value; 10 | } 11 | return self; 12 | } 13 | 14 | - (instancetype)initWithNumber:(NSNumber *)value { 15 | self = [super init]; 16 | if (self) { 17 | _stringValue = [value stringValue]; 18 | } 19 | return self; 20 | } 21 | 22 | - (instancetype)initWithBool:(BOOL)value { 23 | self = [super init]; 24 | if (self) { 25 | _stringValue = [NSString stringWithFormat:@"%@", value ? @"true" : @"false"]; 26 | } 27 | return self; 28 | } 29 | 30 | 31 | + (ARTStringifiable *)withString:(NSString *)value { 32 | return [[ARTStringifiable alloc] initWithString:value]; 33 | } 34 | 35 | + (ARTStringifiable *)withNumber:(NSNumber *)value { 36 | return [[ARTStringifiable alloc] initWithNumber:value]; 37 | } 38 | 39 | + (ARTStringifiable *)withBool:(BOOL)value { 40 | return [[ARTStringifiable alloc] initWithBool:value]; 41 | } 42 | 43 | @end 44 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTRestChannels+Private.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import "ARTQueuedDealloc.h" 3 | #import "ARTRestChannel+Private.h" 4 | 5 | @class ARTRestChannel; 6 | @class ARTRestInternal; 7 | 8 | NS_ASSUME_NONNULL_BEGIN 9 | 10 | @interface ARTRestChannelsInternal : NSObject 11 | 12 | - (ARTRestChannelInternal *)get:(NSString *)name; 13 | - (ARTRestChannelInternal *)get:(NSString *)name options:(ARTChannelOptions *)options; 14 | - (id)copyIntoIteratorWithMapper:(ARTRestChannel *(^)(ARTRestChannelInternal *))mapper; 15 | 16 | - (instancetype)initWithRest:(ARTRestInternal *)rest logger:(ARTInternalLog *)logger; 17 | - (ARTRestChannelInternal *)_getChannel:(NSString *)name options:(ARTChannelOptions * _Nullable)options addPrefix:(BOOL)addPrefix; 18 | 19 | - (BOOL)exists:(NSString *)name; 20 | - (void)release:(NSString *)name; 21 | 22 | @end 23 | 24 | @interface ARTRestChannels () 25 | 26 | @property (nonatomic, readonly) ARTRestChannelsInternal *internal; 27 | 28 | - (instancetype)initWithInternal:(ARTRestChannelsInternal *)internal queuedDealloc:(ARTQueuedDealloc *)dealloc; 29 | 30 | @end 31 | 32 | NS_ASSUME_NONNULL_END 33 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTDictionarySerializable.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | NS_ASSUME_NONNULL_BEGIN 4 | 5 | /** 6 | * Protocol for summary types that can initialize from NSDictionary. 7 | * Similar to how ARTJsonLikeEncoder parses dictionaries. 8 | */ 9 | NS_SWIFT_SENDABLE 10 | @protocol ARTDictionarySerializable 11 | 12 | /** 13 | * Initializes the summary type from an NSDictionary. 14 | * @param dictionary The dictionary containing the summary data 15 | * @return An initialized instance or nil if parsing fails 16 | */ 17 | - (nullable instancetype)initWithDictionary:(NSDictionary *)dictionary; 18 | 19 | /** 20 | * Creates a summary type instance from an NSDictionary. 21 | * @param dictionary The dictionary containing the summary data 22 | * @return A new instance or nil if parsing fails 23 | */ 24 | + (nullable instancetype)createFromDictionary:(NSDictionary *)dictionary; 25 | 26 | /** 27 | * Writes the summary type data to a mutable dictionary. 28 | * @param dictionary The dictionary to write to 29 | */ 30 | - (void)writeToDictionary:(NSMutableDictionary *)dictionary; 31 | 32 | @end 33 | 34 | NS_ASSUME_NONNULL_END 35 | -------------------------------------------------------------------------------- /Test/AblyTests/Test Utilities/TestProxyTransportFactory.swift: -------------------------------------------------------------------------------- 1 | import Ably.Private 2 | 3 | class TestProxyTransportFactory: RealtimeTransportFactory { 4 | // This value will be used by all TestProxyTransportFactory instances created by this factory (including those created before this property is updated). 5 | var fakeNetworkResponse: FakeNetworkResponse? 6 | 7 | // This value will be used by all TestProxyTransportFactory instances created by this factory (including those created before this property is updated). 8 | var networkConnectEvent: ((ARTRealtimeTransport, URL) -> Void)? 9 | 10 | var transportCreatedEvent: ((ARTRealtimeTransport) -> Void)? 11 | 12 | func transport(withRest rest: ARTRestInternal, options: ARTClientOptions, resumeKey: String?, logger: InternalLog) -> ARTRealtimeTransport { 13 | let testProxyTransport = TestProxyTransport( 14 | factory: self, 15 | rest: rest, 16 | options: options, 17 | resumeKey: resumeKey, 18 | logger: logger 19 | ) 20 | 21 | transportCreatedEvent?(testProxyTransport) 22 | 23 | return testProxyTransport 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Ably-SoakTest-AppUITests/SoakTestReachability.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SoakTestReachability.swift 3 | // Ably-iOS-SoakTest 4 | // 5 | // Created by Toni Cárdenas on 09/11/2019. 6 | // Copyright © 2019 Ably. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import Ably.Private 11 | 12 | class SoakTestReachability : NSObject, ARTReachability { 13 | let queue: DispatchQueue 14 | var callback: ((Bool) -> Void)? 15 | var isReachable = true 16 | 17 | required init(logger: ARTLog, queue: DispatchQueue) { 18 | self.queue = queue 19 | super.init() 20 | waitAndToggle() 21 | } 22 | 23 | func listen(forHost host: String, callback: @escaping (Bool) -> Void) { 24 | self.callback = callback 25 | } 26 | 27 | func off() { 28 | self.callback = nil 29 | } 30 | 31 | func waitAndToggle() { 32 | queue.afterSeconds(between: (0.1 ... 60.0 * 5)) { 33 | self.isReachable = !self.isReachable 34 | 35 | if let callback = self.callback { 36 | callback(self.isReachable) 37 | } 38 | 39 | self.waitAndToggle() 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTAttachRetryState.h: -------------------------------------------------------------------------------- 1 | @import Foundation; 2 | #import 3 | 4 | @class ARTRetryAttempt; 5 | @class ARTInternalLog; 6 | @protocol ARTRetryDelayCalculator; 7 | 8 | NS_ASSUME_NONNULL_BEGIN 9 | 10 | /** 11 | Maintains the state that an `ARTRealtimeChannel` instance needs in order to determine the duration to wait before retrying an attach. Wraps a sequence of `ARTRetrySequence` objects. 12 | */ 13 | NS_SWIFT_NAME(AttachRetryState) 14 | @interface ARTAttachRetryState: NSObject 15 | 16 | - (instancetype)initWithRetryDelayCalculator:(id)retryDelayCalculator 17 | logger:(ARTInternalLog *)logger 18 | logMessagePrefix:(NSString *)logMessagePrefix; 19 | - (instancetype)init NS_UNAVAILABLE; 20 | 21 | /** 22 | Calls `addRetryAttempt` on the current retry sequence. 23 | */ 24 | - (ARTRetryAttempt *)addRetryAttempt; 25 | 26 | /** 27 | Resets the retry sequence when the channel leaves the sequence of `SUSPENDED` <-> `ATTACHING` state changes. 28 | */ 29 | - (void)channelWillTransitionToState:(ARTRealtimeChannelState)state; 30 | 31 | @end 32 | 33 | NS_ASSUME_NONNULL_END 34 | -------------------------------------------------------------------------------- /Source/ARTJsonEncoder.m: -------------------------------------------------------------------------------- 1 | #import "ARTJsonEncoder.h" 2 | 3 | @implementation ARTJsonEncoder 4 | 5 | - (NSString *)mimeType { 6 | return @"application/json"; 7 | } 8 | 9 | - (ARTEncoderFormat)format { 10 | return ARTEncoderFormatJson; 11 | } 12 | 13 | - (NSString *)formatAsString { 14 | return @"json"; 15 | } 16 | 17 | - (id)decode:(NSData *)data error:(NSError **)error { 18 | return [NSJSONSerialization JSONObjectWithData:data options:0 error:error]; 19 | } 20 | 21 | - (NSData *)encode:(id)obj error:(NSError **)error { 22 | @try { 23 | NSJSONWritingOptions options; 24 | if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)) { 25 | options = NSJSONWritingSortedKeys; 26 | } 27 | else { 28 | options = 0; 29 | } 30 | return [NSJSONSerialization dataWithJSONObject:obj options:options error:error]; 31 | } 32 | @catch (NSException *exception) { 33 | if (error) { 34 | *error = [[NSError alloc] initWithDomain:ARTAblyErrorDomain code:ARTClientCodeErrorInvalidType userInfo:@{NSLocalizedDescriptionKey: exception.reason}]; 35 | } 36 | return nil; 37 | } 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTConnectRetryState.h: -------------------------------------------------------------------------------- 1 | @import Foundation; 2 | #import 3 | 4 | @class ARTRetryAttempt; 5 | @class ARTInternalLog; 6 | @protocol ARTRetryDelayCalculator; 7 | 8 | NS_ASSUME_NONNULL_BEGIN 9 | 10 | /** 11 | Maintains the state that an `ARTRealtime` instance needs in order to determine the duration to wait before retrying a connection. Wraps a sequence of `ARTRetrySequence` objects. 12 | */ 13 | NS_SWIFT_NAME(ConnectRetryState) 14 | @interface ARTConnectRetryState: NSObject 15 | 16 | - (instancetype)initWithRetryDelayCalculator:(id)retryDelayCalculator 17 | logger:(ARTInternalLog *)logger 18 | logMessagePrefix:(NSString *)logMessagePrefix; 19 | - (instancetype)init NS_UNAVAILABLE; 20 | 21 | /** 22 | Calls `addRetryAttempt` on the current retry sequence. 23 | */ 24 | - (ARTRetryAttempt *)addRetryAttempt; 25 | 26 | /** 27 | Resets the retry sequence when the channel leaves the sequence of `DISCONNECTED` <-> `CONNECTING` state changes. 28 | */ 29 | - (void)connectionWillTransitionToState:(ARTRealtimeConnectionState)state; 30 | 31 | @end 32 | 33 | NS_ASSUME_NONNULL_END 34 | -------------------------------------------------------------------------------- /Source/SocketRocket/Internal/IOConsumer/ARTSRIOConsumerPool.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2012 Square Inc. 3 | // Portions Copyright (c) 2016-present, Facebook, Inc. 4 | // 5 | // All rights reserved. 6 | // 7 | // This source code is licensed under the BSD-style license found in the 8 | // LICENSE file in the root directory of this source tree. An additional grant 9 | // of patent rights can be found in the PATENTS file in the same directory. 10 | // 11 | 12 | #import 13 | 14 | #import "ARTSRIOConsumer.h" // TODO: (nlutsenko) Convert to @class and constants file for block types 15 | 16 | // This class is not thread-safe, and is expected to always be run on the same queue. 17 | @interface ARTSRIOConsumerPool : NSObject 18 | 19 | - (instancetype)initWithBufferCapacity:(NSUInteger)poolSize; 20 | 21 | - (ARTSRIOConsumer *)consumerWithScanner:(stream_scanner)scanner 22 | handler:(data_callback)handler 23 | bytesNeeded:(size_t)bytesNeeded 24 | readToCurrentFrame:(BOOL)readToCurrentFrame 25 | unmaskBytes:(BOOL)unmaskBytes; 26 | - (void)returnConsumer:(ARTSRIOConsumer *)consumer; 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /Source/include/Ably/ARTRealtimeChannels.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import 4 | 5 | NS_ASSUME_NONNULL_BEGIN 6 | 7 | /// :nodoc: 8 | @protocol ARTRealtimeChannelsProtocol 9 | 10 | // We copy this from the parent class and replace ChannelType by ARTRealtimeChannel * because 11 | // Swift ignores Objective-C generics and thinks this is returning an id, failing to compile. 12 | // Thus, we can't make ARTRealtimeChannels inherit from ARTChannels; we have to compose them instead. 13 | - (BOOL)exists:(NSString *)name; 14 | - (void)release:(NSString *)name callback:(nullable ARTCallback)errorInfo; 15 | - (void)release:(NSString *)name; 16 | 17 | @end 18 | 19 | /// :nodoc: 20 | NS_SWIFT_SENDABLE 21 | @interface ARTRealtimeChannels : NSObject 22 | 23 | - (ARTRealtimeChannel *)get:(NSString *)name; 24 | - (ARTRealtimeChannel *)get:(NSString *)name options:(ARTRealtimeChannelOptions *)options; 25 | 26 | /** 27 | * Iterates through the existing channels. 28 | * 29 | * @return Each iteration returns an `ARTRealtimeChannel` object. 30 | */ 31 | - (id)iterate; 32 | 33 | @end 34 | 35 | NS_ASSUME_NONNULL_END 36 | -------------------------------------------------------------------------------- /Test/AblyTests/Tests/RetrySequenceTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import Ably.Private 3 | 4 | class RetrySequenceTests: XCTestCase { 5 | func test_addRetryAttempt() { 6 | // Given: a RetrySequence initialized with a delay calculator that returns arbitrary values from its `delay(forRetryNumber:)` method... 7 | let delays: [TimeInterval] = [0.1, 0.3, 0.9] 8 | let calculator = MockRetryDelayCalculator(delays: delays) 9 | 10 | let sequence = RetrySequence(delayCalculator: calculator) 11 | 12 | // When: addRetryAttempt is called an arbitrarily-chosen number n ( = 3) times on the retry sequence... 13 | let firstRetryAttempt = sequence.addRetryAttempt() 14 | let secondRetryAttempt = sequence.addRetryAttempt() 15 | let thirdRetryAttempt = sequence.addRetryAttempt() 16 | 17 | // Then: the list of `delay` properties of the returned RetryAttempt objects matches those returned by the calculator's `delay(forRetryNumber: x)` method for x = 1, ... , n. 18 | XCTAssertEqual(firstRetryAttempt.delay, delays[0]) 19 | XCTAssertEqual(secondRetryAttempt.delay, delays[1]) 20 | XCTAssertEqual(thirdRetryAttempt.delay, delays[2]) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Source/include/Ably/ARTDeviceIdentityTokenDetails.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | NS_ASSUME_NONNULL_BEGIN 4 | 5 | /** 6 | * An object representing a unique device identity token used to communicate with APNS. 7 | */ 8 | @interface ARTDeviceIdentityTokenDetails : NSObject 9 | 10 | /** 11 | Token string. 12 | */ 13 | @property (nonatomic, readonly) NSString *token; 14 | 15 | /** 16 | Contains the time the token was issued in milliseconds. 17 | */ 18 | @property (nonatomic, readonly) NSDate *issued; 19 | 20 | /** 21 | Contains the expiry time in milliseconds. 22 | */ 23 | @property (nonatomic, readonly) NSDate *expires; 24 | 25 | /** 26 | Contains the capability JSON stringified. 27 | */ 28 | @property (nonatomic, readonly) NSString *capability; 29 | 30 | /** 31 | Contains the clientId assigned to the token if provided. 32 | */ 33 | @property (nonatomic, readonly, nullable) NSString *clientId; 34 | 35 | /// :nodoc: 36 | - (instancetype)init UNAVAILABLE_ATTRIBUTE; 37 | 38 | /// :nodoc: 39 | - (instancetype)initWithToken:(NSString *)token issued:(NSDate *)issued expires:(NSDate *)expires capability:(NSString *)capability clientId:(nullable NSString *)clientId; 40 | 41 | @end 42 | 43 | NS_ASSUME_NONNULL_END 44 | -------------------------------------------------------------------------------- /Source/ARTTestClientOptions.m: -------------------------------------------------------------------------------- 1 | #import "ARTTestClientOptions.h" 2 | #import "ARTDefault.h" 3 | #import "ARTFallback+Private.h" 4 | #import "ARTRealtimeTransportFactory.h" 5 | #import "ARTJitterCoefficientGenerator.h" 6 | 7 | @implementation ARTTestClientOptions 8 | 9 | - (instancetype)init { 10 | if (self = [super init]) { 11 | _realtimeRequestTimeout = [ARTDefault realtimeRequestTimeout]; 12 | _shuffleArray = ARTFallback_shuffleArray; 13 | _transportFactory = [[ARTDefaultRealtimeTransportFactory alloc] init]; 14 | _jitterCoefficientGenerator = [[ARTDefaultJitterCoefficientGenerator alloc] init]; 15 | } 16 | 17 | return self; 18 | } 19 | 20 | - (nonnull id)copyWithZone:(nullable NSZone *)zone { 21 | ARTTestClientOptions *const copied = [[ARTTestClientOptions alloc] init]; 22 | copied.channelNamePrefix = self.channelNamePrefix; 23 | copied.realtimeRequestTimeout = self.realtimeRequestTimeout; 24 | copied.shuffleArray = self.shuffleArray; 25 | copied.transportFactory = self.transportFactory; 26 | copied.reconnectionRealtimeHost = self.reconnectionRealtimeHost; 27 | copied.jitterCoefficientGenerator = self.jitterCoefficientGenerator; 28 | 29 | return copied; 30 | } 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTPushActivationStateMachine.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @class ARTErrorInfo; 4 | @class ARTPushActivationState; 5 | @class ARTPushActivationEvent; 6 | @class ARTRest; 7 | 8 | @protocol ARTDeviceStorage; 9 | 10 | NS_ASSUME_NONNULL_BEGIN 11 | 12 | @interface ARTPushActivationStateMachine : NSObject 13 | 14 | @property (readonly, nonatomic) ARTPushActivationEvent *lastEvent; 15 | @property (readonly, nonatomic) ARTPushActivationState *current; 16 | @property (readonly, nonatomic) NSArray *pendingEvents; 17 | 18 | - (instancetype)init NS_UNAVAILABLE; 19 | + (instancetype)new NS_UNAVAILABLE; 20 | 21 | - (void)sendEvent:(ARTPushActivationEvent *)event; 22 | 23 | @end 24 | 25 | @interface ARTPushActivationStateMachine (Protected) 26 | - (void)deviceRegistration:(nullable ARTErrorInfo *)error; 27 | - (void)syncDevice; 28 | - (void)deviceUpdateRegistration:(nullable ARTErrorInfo *)error; 29 | - (void)deviceUnregistration:(nullable ARTErrorInfo *)error; 30 | - (void)callActivatedCallback:(nullable ARTErrorInfo *)error; 31 | - (void)callDeactivatedCallback:(nullable ARTErrorInfo *)error; 32 | - (void)callUpdatedCallback:(nullable ARTErrorInfo *)error; 33 | @end 34 | 35 | NS_ASSUME_NONNULL_END 36 | -------------------------------------------------------------------------------- /Examples/AblyPush/AblyPushExample/App.swift: -------------------------------------------------------------------------------- 1 | import Ably 2 | import SwiftUI 3 | 4 | @main 5 | struct AblyCocoaAPNSExampleApp: App { 6 | 7 | @UIApplicationDelegateAdaptor private var appDelegate: AppDelegate 8 | 9 | var body: some Scene { 10 | WindowGroup { 11 | ContentView() 12 | } 13 | } 14 | } 15 | 16 | class AppDelegate: NSObject, UIApplicationDelegate { 17 | 18 | func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { 19 | AblyHelper.shared.defaultDeviceToken = deviceToken.deviceTokenString 20 | ARTPush.didRegisterForRemoteNotifications(withDeviceToken: deviceToken, realtime: AblyHelper.shared.realtime) 21 | } 22 | 23 | func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) { 24 | ARTPush.didFailToRegisterForRemoteNotificationsWithError(error, realtime: AblyHelper.shared.realtime) 25 | } 26 | } 27 | 28 | extension Data { 29 | 30 | var deviceTokenString: String { 31 | var result = "" 32 | for byte in self { 33 | result += String(format: "%02x", UInt(byte)) 34 | } 35 | return result 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Source/ARTMessageAnnotations.m: -------------------------------------------------------------------------------- 1 | #import "ARTDefault.h" 2 | #import "ARTMessageAnnotations.h" 3 | 4 | @implementation ARTMessageAnnotations 5 | 6 | - (instancetype)init { 7 | self = [super init]; 8 | if (self) { 9 | _summary = nil; 10 | } 11 | return self; 12 | } 13 | 14 | - (id)copyWithZone:(NSZone *)zone { 15 | ARTMessageAnnotations *annotations = [[[self class] allocWithZone:zone] init]; 16 | annotations.summary = self.summary; 17 | return annotations; 18 | } 19 | 20 | - (void)writeToDictionary:(NSMutableDictionary *)dictionary { 21 | if (self.summary) { 22 | dictionary[@"summary"] = self.summary; 23 | } 24 | } 25 | 26 | + (instancetype)createFromDictionary:(NSDictionary *)jsonObject { 27 | ARTMessageAnnotations *annotations = [[ARTMessageAnnotations alloc] init]; 28 | annotations.summary = [jsonObject objectForKey:@"summary"]; 29 | return annotations; 30 | } 31 | 32 | - (NSString *)description { 33 | NSMutableString *description = [NSMutableString stringWithFormat:@"<%@: %p> {\n", self.class, self]; 34 | [description appendFormat:@" summary: %@\n", self.summary]; 35 | [description appendFormat:@"}"]; 36 | return description; 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /Source/SocketRocket/Internal/IOConsumer/ARTSRIOConsumer.m: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2012 Square Inc. 3 | // Portions Copyright (c) 2016-present, Facebook, Inc. 4 | // 5 | // All rights reserved. 6 | // 7 | // This source code is licensed under the BSD-style license found in the 8 | // LICENSE file in the root directory of this source tree. An additional grant 9 | // of patent rights can be found in the PATENTS file in the same directory. 10 | // 11 | 12 | #import "ARTSRIOConsumer.h" 13 | 14 | @implementation ARTSRIOConsumer 15 | 16 | @synthesize bytesNeeded = _bytesNeeded; 17 | @synthesize consumer = _scanner; 18 | @synthesize handler = _handler; 19 | @synthesize readToCurrentFrame = _readToCurrentFrame; 20 | @synthesize unmaskBytes = _unmaskBytes; 21 | 22 | - (void)resetWithScanner:(stream_scanner)scanner 23 | handler:(data_callback)handler 24 | bytesNeeded:(size_t)bytesNeeded 25 | readToCurrentFrame:(BOOL)readToCurrentFrame 26 | unmaskBytes:(BOOL)unmaskBytes 27 | { 28 | _scanner = [scanner copy]; 29 | _handler = [handler copy]; 30 | _bytesNeeded = bytesNeeded; 31 | _readToCurrentFrame = readToCurrentFrame; 32 | _unmaskBytes = unmaskBytes; 33 | assert(_scanner || _bytesNeeded); 34 | } 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /Source/ARTFallback.m: -------------------------------------------------------------------------------- 1 | #import "ARTFallback+Private.h" 2 | 3 | #import "ARTDefault+Private.h" 4 | #import "ARTStatus.h" 5 | #import "ARTHttp.h" 6 | 7 | void (^const ARTFallback_shuffleArray)(NSMutableArray *) = ^void(NSMutableArray *a) { 8 | for (NSUInteger i = a.count; i > 1; i--) { 9 | [a exchangeObjectAtIndex:i - 1 withObjectAtIndex:arc4random_uniform((u_int32_t)i)]; 10 | } 11 | }; 12 | 13 | @interface ARTFallback () 14 | 15 | @end 16 | 17 | @implementation ARTFallback 18 | 19 | - (instancetype)initWithFallbackHosts:(nullable NSArray *)fallbackHosts shuffleArray:(void (^)(NSMutableArray *))shuffleArray { 20 | self = [super init]; 21 | if (self) { 22 | if (fallbackHosts == nil || fallbackHosts.count == 0) { 23 | return nil; 24 | } 25 | self.hosts = [[NSMutableArray alloc] initWithArray:fallbackHosts]; 26 | shuffleArray(self.hosts); 27 | } 28 | return self; 29 | } 30 | 31 | - (NSString *)popFallbackHost { 32 | if ([self.hosts count] == 0) { 33 | return nil; 34 | } 35 | NSString *host = [self.hosts lastObject]; 36 | [self.hosts removeLastObject]; 37 | return host; 38 | } 39 | 40 | - (BOOL)isEmpty { 41 | return self.hosts.count == 0; 42 | } 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTGCD.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | NS_ASSUME_NONNULL_BEGIN 4 | 5 | @interface ARTScheduledBlockHandle : NSObject 6 | - (instancetype)initWithDelay:(NSTimeInterval)delay queue:(dispatch_queue_t)queue block:(dispatch_block_t)block; 7 | - (void)cancel; 8 | @end 9 | 10 | ARTScheduledBlockHandle *artDispatchScheduled(NSTimeInterval seconds, dispatch_queue_t queue, dispatch_block_t block); 11 | static inline void artDispatchCancel(ARTScheduledBlockHandle *handle) { 12 | if (handle) { 13 | [handle cancel]; 14 | } 15 | } 16 | 17 | /// Like `dispatch_sync`, but throws an `NSException` if the queue is `nil` at runtime. 18 | /// 19 | /// This is to aid in debugging client crash reports (if you pass a `nil` queue to `dispatch_sync` you get a rather opaque `EXC_BAD_ACCESS`). 20 | void art_dispatch_sync(dispatch_queue_t queue, DISPATCH_NOESCAPE dispatch_block_t block); 21 | 22 | /// Like `dispatch_async`, but throws an `NSException` if the queue is `nil` at runtime. 23 | /// 24 | /// This is to aid in debugging client crash reports (if you pass a `nil` block to `dispatch_async` you get a rather opaque `EXC_BAD_ACCESS`). 25 | void art_dispatch_async(dispatch_queue_t queue, dispatch_block_t block); 26 | 27 | NS_ASSUME_NONNULL_END 28 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Swift Package Manager 2 | 3 | # Start of .gitignore created by Swift Package Manager 4 | .DS_Store 5 | /.build 6 | /Packages 7 | xcuserdata/ 8 | DerivedData/ 9 | .swiftpm/configuration/registries.json 10 | .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata 11 | .netrc 12 | # End of .gitignore created by Swift Package Manager 13 | 14 | ## Xcode 15 | 16 | # This is created when running `xcodebuild`: 17 | build/ 18 | 19 | ## CocoaPods 20 | # 21 | # We recommend against adding the Pods directory to your .gitignore. However 22 | # you should judge for yourself, the pros and cons are mentioned at: 23 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 24 | Pods/ 25 | 26 | ## Carthage 27 | # 28 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 29 | Carthage/Checkouts 30 | Carthage/Build 31 | 32 | # Output from `carthage build` 33 | Ably.framework.zip 34 | 35 | ## Scan 36 | test_output/ 37 | 38 | ## Fastlane 39 | fastlane/report.xml 40 | fastlane/test_output 41 | fastlane/README.md 42 | derived_data/ 43 | 44 | Examples/Tests/Podfile.lock 45 | 46 | ## AppCode 47 | .build 48 | .idea 49 | 50 | ## Jazzy Docs 51 | Docs/jazzy 52 | 53 | ## Tooling 54 | xcparse/ 55 | -------------------------------------------------------------------------------- /Source/include/Ably/ARTWrapperSDKProxyRealtimeChannel.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @class ARTWrapperSDKProxyRealtimeChannel; 5 | @class ARTWrapperSDKProxyPushChannel; 6 | @class ARTWrapperSDKProxyRealtimePresence; 7 | @class ARTWrapperSDKProxyRealtimeAnnotations; 8 | 9 | NS_ASSUME_NONNULL_BEGIN 10 | 11 | /** 12 | * An object which wraps an instance of `ARTRealtimeChannel` 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. 13 | * 14 | * - Important: This class should only be used by Ably-authored SDKs. 15 | */ 16 | NS_SWIFT_SENDABLE 17 | @interface ARTWrapperSDKProxyRealtimeChannel : NSObject 18 | 19 | - (instancetype)init NS_UNAVAILABLE; 20 | 21 | /// The channel that this `ARTWrapperSDKProxyRealtimeChannel` proxies. 22 | @property (nonatomic, readonly) ARTRealtimeChannel *underlyingChannel; 23 | 24 | @property (readonly) ARTWrapperSDKProxyRealtimePresence *presence; 25 | 26 | @property (readonly) ARTWrapperSDKProxyRealtimeAnnotations *annotations; 27 | 28 | #if TARGET_OS_IPHONE 29 | @property (readonly) ARTWrapperSDKProxyPushChannel *push; 30 | #endif 31 | 32 | @end 33 | 34 | NS_ASSUME_NONNULL_END 35 | -------------------------------------------------------------------------------- /.github/issue_template.md: -------------------------------------------------------------------------------- 1 | ### Which version of the Ably SDK are you using? 2 | E.g. `1.0.11` 3 | 4 | ### On which platform does the issue happen? 5 | E.g. `iOS11` 6 | 7 | ### Are you using Carthage? 8 | If yes, specify the version (`carthage version`) 9 | 10 | ### Are you using Cocoapods? 11 | If yes, specify the version (`pod --version`) 12 | 13 | ### Which version of Xcode are you using? 14 | (`xcodebuild -version`) 15 | 16 | ### What did you do? 17 | Describe the problem. 18 | ``` 19 | Add a short snippet of code to show the problem 20 | ``` 21 | 22 | ### What did you expect to happen? 23 | Describe the expected outcome. 24 | 25 | ### What happened instead? 26 | Describe what happened instead. 27 | 28 | ``` 29 | Add relevant console logs. 30 | ``` 31 | 32 | **Tip:** set the log level to debug. E.g. `realtime.logger.logLevel = .debug` and take a look at our [troubleshooting guide](https://support.ably.io/solution/articles/3000063743-guide-information-we-need-to-help-you-diagnose-problems) 33 | 34 | ### Link to sample project 35 | Feel free to link to a sample project that showcases the issue. 36 | 37 | P.S. If you are an [Ably Enterprise customer](https://www.ably.io/pricing/enterprise), please [get in touch](https://www.ably.io/contact) with a link to this issue to get prioritized support. 38 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTContinuousClock.h: -------------------------------------------------------------------------------- 1 | @import Foundation; 2 | 3 | @class ARTContinuousClockInstant; 4 | 5 | NS_ASSUME_NONNULL_BEGIN 6 | 7 | /** 8 | A clock that increments monotonically, including while the system is asleep. 9 | 10 | - Note: We don't give this one an `NS_SWIFT_NAME`, to avoid confusion with the Swift standard library type also named `ContinuousClock`. 11 | */ 12 | @interface ARTContinuousClock: NSObject 13 | 14 | /** 15 | Returns the current instant in time. 16 | */ 17 | - (ARTContinuousClockInstant *)now; 18 | 19 | /** 20 | Returns the instant in time that occurs after a given duration has elapsed in relation to a given instant in time. 21 | */ 22 | - (ARTContinuousClockInstant *)addingDuration:(NSTimeInterval)duration toInstant:(ARTContinuousClockInstant *)instant; 23 | 24 | @end 25 | 26 | /** 27 | Represents an instant in time, as described by an instance of `ARTContinuousClock`. 28 | */ 29 | @interface ARTContinuousClockInstant: NSObject 30 | 31 | - (instancetype)init NS_UNAVAILABLE; 32 | 33 | /** 34 | Returns `YES` if and only if the instant in time represented by `other` occurs after that represented by the receiver. 35 | */ 36 | - (BOOL)isAfter:(ARTContinuousClockInstant *)other NS_SWIFT_NAME(isAfter(_:)); 37 | 38 | @end 39 | 40 | NS_ASSUME_NONNULL_END 41 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTLogAdapter.h: -------------------------------------------------------------------------------- 1 | @import Foundation; 2 | 3 | #import "ARTVersion2Log.h" 4 | 5 | @class ARTLog; 6 | 7 | NS_ASSUME_NONNULL_BEGIN 8 | 9 | /** 10 | `ARTLogAdapter` provides an implementation of `ARTVersion2Log` that writes all log messages to a given instance of `ARTLog`. 11 | 12 | The intention of this class is to allow us to maintain the public API of the SDK, which allows users to provide an `ARTLog` instance, whilst using `ARTVersion2Log` for logging inside the SDK. Upon the next major release of this library, when `ARTVersion2Log` will be renamed `ARTLog` and the current `ARTLog` will be removed, we can remove this class too. 13 | */ 14 | NS_SWIFT_NAME(LogAdapter) 15 | @interface ARTLogAdapter: NSObject 16 | 17 | - (instancetype)init NS_UNAVAILABLE; 18 | 19 | /** 20 | Creates an instance of `ARTLogAdapter` which wraps an underlying `ARTLog` instance. 21 | 22 | - Parameters: 23 | - logger: The `ARTLog` instance to wrap. 24 | */ 25 | - (instancetype)initWithLogger:(ARTLog *)logger; 26 | 27 | /** 28 | `ARTLogAdapter` implements this `ARTVersion2Log` protocol requirement by forwarding the setter and getter calls to its underlying `ARTLog` instance. 29 | */ 30 | @property (nonatomic) ARTLogLevel logLevel; 31 | 32 | @end 33 | 34 | NS_ASSUME_NONNULL_END 35 | -------------------------------------------------------------------------------- /Source/ARTConnectionDetails.m: -------------------------------------------------------------------------------- 1 | #import "ARTConnectionDetails+Private.h" 2 | 3 | @implementation ARTConnectionDetails 4 | 5 | - (instancetype)initWithClientId:(NSString *_Nullable)clientId 6 | connectionKey:(NSString *_Nullable)connectionKey 7 | maxMessageSize:(NSInteger)maxMessageSize 8 | maxFrameSize:(NSInteger)maxFrameSize 9 | maxInboundRate:(NSInteger)maxInboundRate 10 | connectionStateTtl:(NSTimeInterval)connectionStateTtl 11 | serverId:(NSString *)serverId 12 | maxIdleInterval:(NSTimeInterval)maxIdleInterval 13 | objectsGCGracePeriod:(nullable NSNumber *)objectsGCGracePeriod { 14 | if (self = [super init]) { 15 | _clientId = clientId; 16 | _connectionKey = connectionKey; 17 | _maxMessageSize = maxMessageSize; 18 | _maxFrameSize = maxFrameSize; 19 | _maxInboundRate = maxInboundRate; 20 | _connectionStateTtl = connectionStateTtl; 21 | _serverId = serverId; 22 | _maxIdleInterval = maxIdleInterval; 23 | _objectsGCGracePeriod = objectsGCGracePeriod; 24 | } 25 | return self; 26 | } 27 | 28 | - (void)setMaxIdleInterval:(NSTimeInterval)seconds { 29 | _maxIdleInterval = seconds; 30 | } 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /Test/AblyTests/Tests/GCDTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import Ably.Private 3 | 4 | class GCDTests: XCTestCase { 5 | func testScheduledBlockHandleDerefsBlockAfterInvoke() { 6 | let invokedExpectation = self.expectation(description: "scheduled block invoked") 7 | 8 | // retain counter: 1 9 | var object = NSObject() 10 | 11 | // store reference for above weakified 12 | weak var weakObject = object 13 | 14 | // prepare schedule block 15 | var scheduledBlock: ARTScheduledBlockHandle? = artDispatchScheduled(0, .main) { [object] in 16 | // retain counter +1 -> sum: 2 17 | _ = object 18 | invokedExpectation.fulfill() 19 | } 20 | 21 | // invoke block 22 | _ = scheduledBlock 23 | 24 | waitForExpectations(timeout: 2, handler: nil) 25 | 26 | // destroy block reference 27 | // `object` retain counter -1, sum: 1 28 | scheduledBlock = nil 29 | 30 | // assign new object to old variable 31 | // at this point old `object` should be destroyed, retain counter: -1, sum: 0 -> Destroy 32 | object = NSObject() 33 | 34 | // check if old `object` reference was destroyed 35 | XCTAssertNil(weakObject) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTConnectionStateChangeParams.h: -------------------------------------------------------------------------------- 1 | @import Foundation; 2 | 3 | @class ARTErrorInfo; 4 | @class ARTRetryAttempt; 5 | 6 | NS_ASSUME_NONNULL_BEGIN 7 | 8 | /** 9 | Provides parameters for a request to perform an operation that may cause an `ARTRealtimeInternal` instance to emit a connection state change. 10 | 11 | `ARTRealtimeInternal` will incorporate this data into the `ARTConnectionStateChange` object that it emits as a result of the connection state change. 12 | */ 13 | NS_SWIFT_NAME(ConnectionStateChangeParams) 14 | @interface ARTConnectionStateChangeParams: NSObject 15 | 16 | /** 17 | Information about the error that triggered this state change, if any. 18 | */ 19 | @property (nullable, nonatomic, readonly) ARTErrorInfo *errorInfo; 20 | 21 | @property (nullable, nonatomic, readonly) ARTRetryAttempt *retryAttempt; 22 | 23 | @property (assign, nonatomic) BOOL resumed; 24 | 25 | /** 26 | Creates an `ARTConnectionStateChangeParams` instance whose `errorInfo` is `nil`. 27 | */ 28 | - (instancetype)init; 29 | 30 | - (instancetype)initWithErrorInfo:(nullable ARTErrorInfo *)errorInfo; 31 | 32 | - (instancetype)initWithErrorInfo:(nullable ARTErrorInfo *)errorInfo 33 | retryAttempt:(nullable ARTRetryAttempt *)retryAttempt NS_DESIGNATED_INITIALIZER; 34 | 35 | @end 36 | 37 | NS_ASSUME_NONNULL_END 38 | -------------------------------------------------------------------------------- /Test/AblyTests/Test Utilities/MockJitterCoefficientGenerator.swift: -------------------------------------------------------------------------------- 1 | import Ably.Private 2 | 3 | /// A mock instance of `JitterCoefficientGenerator`, whose `generateJitterCoefficient()` method returns values from a provided sequence. 4 | /// 5 | /// This class can safely be used across threads. 6 | class MockJitterCoefficientGenerator: JitterCoefficientGenerator { 7 | private var iterator: any IteratorProtocol 8 | private let semaphore = DispatchSemaphore(value: 1) 9 | 10 | /// Creates a jitter coefficient generator whose `generateJitterCoefficient()` method returns values from a provided sequence. 11 | /// 12 | /// - Params: 13 | /// - coefficients: A sequence of values, each in the range (0.8 ... 1). If `generateJitterCoefficient()` is called when there are no values left to iterate in the sequence, a runtime exception will occur. 14 | init(coefficients: some Sequence) { 15 | self.iterator = coefficients.makeIterator() 16 | } 17 | 18 | func generateJitterCoefficient() -> Double { 19 | semaphore.wait() 20 | guard let coefficient = iterator.next() else { 21 | fatalError("Ran out of jitter coefficients") 22 | } 23 | semaphore.signal() 24 | precondition((0.8...1.0).contains(coefficient)) 25 | return coefficient 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTVersion2Log.h: -------------------------------------------------------------------------------- 1 | @import Foundation; 2 | #import 3 | 4 | NS_ASSUME_NONNULL_BEGIN 5 | 6 | /** 7 | The `ARTVersion2Log` protocol represents a logger object that handles data emitted by the SDK's logging system. It will be renamed `ARTLog` in the next major release of the SDK (replacing the existing class), at which point users of the SDK will need to provide an implementation of this protocol if they wish to replace the SDK's default logger. 8 | 9 | The initial interface of `ARTVersion2Log` is based on that of the `ARTLog` class. However, its design will evolve as we gather further information about the following things: 10 | 11 | 1. Requirements for the information logged by the SDK — see issues #1623 and #1624. 12 | 13 | 2. Requirements for the data emitted by the SDK's logging system — see issues #1618 and #1625. 14 | */ 15 | NS_SWIFT_NAME(Version2Log) 16 | @protocol ARTVersion2Log 17 | 18 | @property (nonatomic) ARTLogLevel logLevel; 19 | 20 | /** 21 | - Parameters: 22 | - fileName: The base name (e.g. given an absolute path `/foo/bar/baz`, its base name is `baz`) of the file from which the log message was emitted. 23 | */ 24 | - (void)log:(NSString *)message withLevel:(ARTLogLevel)level file:(NSString *)fileName line:(NSInteger)line; 25 | 26 | @end 27 | 28 | NS_ASSUME_NONNULL_END 29 | -------------------------------------------------------------------------------- /Source/SocketRocket/Internal/Utilities/ARTSRMutex.m: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2016-present, Facebook, Inc. 3 | // All rights reserved. 4 | // 5 | // This source code is licensed under the BSD-style license found in the 6 | // LICENSE file in the root directory of this source tree. An additional grant 7 | // of patent rights can be found in the PATENTS file in the same directory. 8 | // 9 | 10 | #import "ARTSRMutex.h" 11 | 12 | #import 13 | 14 | NS_ASSUME_NONNULL_BEGIN 15 | 16 | ARTSRMutex ARTSRMutexInitRecursive(void) 17 | { 18 | pthread_mutex_t *mutex = malloc(sizeof(pthread_mutex_t)); 19 | pthread_mutexattr_t attributes; 20 | 21 | pthread_mutexattr_init(&attributes); 22 | pthread_mutexattr_settype(&attributes, PTHREAD_MUTEX_RECURSIVE); 23 | pthread_mutex_init(mutex, &attributes); 24 | pthread_mutexattr_destroy(&attributes); 25 | 26 | return mutex; 27 | } 28 | 29 | void ARTSRMutexDestroy(ARTSRMutex mutex) 30 | { 31 | pthread_mutex_destroy(mutex); 32 | free(mutex); 33 | } 34 | 35 | __attribute__((no_thread_safety_analysis)) 36 | void ARTSRMutexLock(ARTSRMutex mutex) 37 | { 38 | pthread_mutex_lock(mutex); 39 | } 40 | 41 | __attribute__((no_thread_safety_analysis)) 42 | void ARTSRMutexUnlock(ARTSRMutex mutex) 43 | { 44 | pthread_mutex_unlock(mutex); 45 | } 46 | 47 | NS_ASSUME_NONNULL_END 48 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTProtocolMessage+Private.h: -------------------------------------------------------------------------------- 1 | /// ARTProtocolMessageFlag bitmask 2 | typedef NS_OPTIONS(NSUInteger, ARTProtocolMessageFlag) { 3 | ARTProtocolMessageFlagHasPresence = (1UL << 0), 4 | ARTProtocolMessageFlagHasBacklog = (1UL << 1), 5 | ARTProtocolMessageFlagResumed = (1UL << 2), 6 | ARTProtocolMessageFlagHasLocalPresence = (1UL << 3), 7 | ARTProtocolMessageFlagTransient = (1UL << 4), 8 | ARTProtocolMessageFlagAttachResume = (1UL << 5), 9 | ARTProtocolMessageFlagHasObjects = (1UL << 7), 10 | ARTProtocolMessageFlagPresence = (1UL << 16), 11 | ARTProtocolMessageFlagPublish = (1UL << 17), 12 | ARTProtocolMessageFlagSubscribe = (1UL << 18), 13 | ARTProtocolMessageFlagPresenceSubscribe = (1UL << 19), 14 | ARTProtocolMessageFlagObjectSubscribe = (1UL << 24), 15 | ARTProtocolMessageFlagObjectPublish = (1UL << 25) 16 | }; 17 | 18 | NS_ASSUME_NONNULL_BEGIN 19 | 20 | @interface ARTProtocolMessage () 21 | 22 | @property (readonly, nonatomic) BOOL ackRequired; 23 | 24 | @property (readonly, nonatomic) BOOL hasPresence; 25 | @property (readonly, nonatomic) BOOL hasObjects; 26 | @property (readonly, nonatomic) BOOL hasBacklog; 27 | @property (readonly, nonatomic) BOOL resumed; 28 | 29 | - (BOOL)mergeFrom:(ARTProtocolMessage *)msg maxSize:(NSInteger)maxSize; 30 | 31 | @end 32 | 33 | NS_ASSUME_NONNULL_END 34 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTRestPresence+Private.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import "ARTQueuedDealloc.h" 3 | 4 | NS_ASSUME_NONNULL_BEGIN 5 | 6 | @class ARTRestChannelInternal; 7 | @class ARTInternalLog; 8 | 9 | @interface ARTRestPresenceInternal : NSObject 10 | 11 | - (instancetype)initWithChannel:(ARTRestChannelInternal *)channel logger:(ARTInternalLog *)logger; 12 | 13 | - (void)get:(ARTPaginatedPresenceCallback)callback; 14 | 15 | - (BOOL)get:(ARTPaginatedPresenceCallback)callback error:(NSError *_Nullable *_Nullable)errorPtr; 16 | 17 | - (BOOL)get:(ARTPresenceQuery *)query callback:(ARTPaginatedPresenceCallback)callback error:(NSError *_Nullable *_Nullable)errorPtr; 18 | 19 | - (BOOL)history:(nullable ARTDataQuery *)query wrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents callback:(ARTPaginatedPresenceCallback)callback error:(NSError *_Nullable *_Nullable)errorPtr; 20 | 21 | - (void)historyWithWrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents 22 | completion:(ARTPaginatedPresenceCallback)callback; 23 | 24 | @end 25 | 26 | @interface ARTRestPresence () 27 | 28 | @property (nonatomic, readonly) ARTRestPresenceInternal *internal; 29 | 30 | - (instancetype)initWithInternal:(ARTRestPresenceInternal *)internal queuedDealloc:(ARTQueuedDealloc *)dealloc; 31 | 32 | @end 33 | 34 | NS_ASSUME_NONNULL_END 35 | -------------------------------------------------------------------------------- /Scripts/set-version.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | source "$(dirname "$0")/version-constants.sh" 5 | 6 | if [[ $(git diff --stat) != '' ]]; then 7 | echo "ERROR: Your Git working directory is dirty." 8 | echo "This script creates a commit and a tag, so it needs a clean starting point." 9 | exit 1 10 | fi 11 | 12 | prefix="$VERSION_CONFIG_VAR = " 13 | version_config=$(cat $VERSION_CONFIG_FILE) 14 | OLD_VERSION=${version_config:${#prefix}} 15 | NEW_VERSION="$1" 16 | 17 | if [[ -z "NEW_VERSION" ]]; then 18 | echo "ERROR: You must specify a version." 19 | exit 1 20 | fi 21 | 22 | echo "New version: $NEW_VERSION" 23 | echo "Old version: $OLD_VERSION" 24 | 25 | # Assign new version 26 | echo "$VERSION_CONFIG_VAR = $NEW_VERSION" > $VERSION_CONFIG_FILE 27 | git add Version.xcconfig 28 | 29 | other_files=( 30 | "README.md" 31 | "Scripts/jazzy.sh" 32 | "Source/ARTClientInformation.m" 33 | "Test/AblyTests/Tests/ARTDefaultTests.swift" 34 | "Test/AblyTests/Tests/ClientInformationTests.swift" 35 | "Test/AblyTests/Tests/RealtimeClientConnectionTests.swift" 36 | "Test/AblyTests/Tests/RestClientTests.swift" 37 | "Test/AblyTests/Tests/WrapperSDKProxyTests.swift" 38 | ) 39 | 40 | for file in ${other_files[@]}; 41 | do 42 | sed -i '' -e 's/'"$OLD_VERSION"'/'"$NEW_VERSION"'/g' "${file}" 43 | git add "${file}" 44 | done 45 | 46 | git commit -m "Bump version to $NEW_VERSION." 47 | -------------------------------------------------------------------------------- /Source/ARTNSHTTPURLResponse+ARTPaginated.m: -------------------------------------------------------------------------------- 1 | #import "ARTNSHTTPURLResponse+ARTPaginated.h" 2 | 3 | @implementation NSHTTPURLResponse (ARTPaginated) 4 | 5 | - (NSDictionary *)extractLinks { 6 | NSString *linkHeader = self.allHeaderFields[@"Link"]; 7 | if (!linkHeader) { 8 | return nil; 9 | } 10 | 11 | static NSRegularExpression *linkRegex; 12 | static dispatch_once_t onceToken; 13 | 14 | dispatch_once(&onceToken, ^{ 15 | linkRegex = [NSRegularExpression regularExpressionWithPattern:@"\\s*<([^>]*)>;\\s*rel=\"([^\"]*)\"" options:0 error:nil]; 16 | }); 17 | 18 | NSMutableDictionary *links = [NSMutableDictionary dictionary]; 19 | 20 | NSArray *matches = [linkRegex matchesInString:linkHeader options:0 range:NSMakeRange(0, linkHeader.length)]; 21 | for (NSTextCheckingResult *match in matches) { 22 | NSRange linkUrlRange = [match rangeAtIndex:1]; 23 | NSRange linkRelRange = [match rangeAtIndex:2]; 24 | 25 | NSString *linkUrl = [linkHeader substringWithRange:linkUrlRange]; 26 | NSString *linkRels = [linkHeader substringWithRange:linkRelRange]; 27 | 28 | for (NSString *linkRel in [linkRels componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]) { 29 | [links setObject:linkUrl forKey:linkRel]; 30 | } 31 | } 32 | 33 | return links; 34 | } 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTPushActivationStateMachine+Private.h: -------------------------------------------------------------------------------- 1 | #import "ARTPushActivationStateMachine.h" 2 | 3 | NS_ASSUME_NONNULL_BEGIN 4 | 5 | @class ARTRestInternal; 6 | @protocol ARTPushRegistererDelegate; 7 | @class ARTInternalLog; 8 | 9 | extern NSString *const ARTPushActivationCurrentStateKey; 10 | extern NSString *const ARTPushActivationPendingEventsKey; 11 | 12 | @interface ARTPushActivationStateMachine () 13 | 14 | @property (nonatomic) ARTRestInternal *rest; 15 | 16 | - (instancetype)initWithRest:(ARTRestInternal *)rest 17 | delegate:(id)delegate 18 | logger:(ARTInternalLog *)logger NS_DESIGNATED_INITIALIZER; 19 | 20 | /// The delegate property should be written to only for internal testing purposes. 21 | @property (weak, nonatomic) id delegate; 22 | 23 | @property (nonatomic, copy, nullable) void (^transitions)(ARTPushActivationEvent *event, ARTPushActivationState *from, ARTPushActivationState *to); 24 | @property (nonatomic, copy, nullable) void (^onEvent)(ARTPushActivationEvent *event, ARTPushActivationState *state); 25 | @property (readonly, nonatomic) ARTPushActivationEvent *lastEvent_nosync; 26 | @property (readonly, nonatomic) ARTPushActivationState *current_nosync; 27 | 28 | - (void)registerForAPNS; 29 | 30 | @end 31 | 32 | NS_ASSUME_NONNULL_END 33 | -------------------------------------------------------------------------------- /Examples/AblyCarthage/AblyCarthage/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | 3 | @main 4 | class AppDelegate: UIResponder, UIApplicationDelegate { 5 | 6 | 7 | 8 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 9 | // Override point for customization after application launch. 10 | return true 11 | } 12 | 13 | // MARK: UISceneSession Lifecycle 14 | 15 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { 16 | // Called when a new scene session is being created. 17 | // Use this method to select a configuration to create the new scene with. 18 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) 19 | } 20 | 21 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { 22 | // Called when the user discards a scene session. 23 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. 24 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return. 25 | } 26 | 27 | 28 | } 29 | 30 | -------------------------------------------------------------------------------- /Source/ARTInternalLogCore.m: -------------------------------------------------------------------------------- 1 | #import "ARTInternalLogCore.h" 2 | #import "ARTInternalLogCore+Testing.h" 3 | #import "ARTVersion2Log.h" 4 | #import "ARTClientOptions.h" 5 | #import "ARTLogAdapter.h" 6 | 7 | @implementation ARTDefaultInternalLogCore 8 | 9 | - (instancetype)initWithLogger:(id)logger { 10 | if (self = [super init]) { 11 | _logger = logger; 12 | } 13 | 14 | return self; 15 | } 16 | 17 | - (instancetype)initWithClientOptions:(ARTClientOptions *)options { 18 | if (options.logLevel != ARTLogLevelNone) { 19 | options.logHandler.logLevel = options.logLevel; 20 | } 21 | 22 | id logger = [[ARTLogAdapter alloc] initWithLogger:options.logHandler]; 23 | return [self initWithLogger:logger]; 24 | } 25 | 26 | // MARK: Logging 27 | 28 | - (void)log:(NSString *)message withLevel:(ARTLogLevel)level file:(const char *)fileName line:(NSInteger)line { 29 | NSString *const fileNameNSString = [NSString stringWithUTF8String:fileName]; 30 | NSString *const lastPathComponent = fileNameNSString ? fileNameNSString.lastPathComponent : @""; 31 | [self.logger log:message withLevel:level file:lastPathComponent line:line]; 32 | } 33 | 34 | // MARK: Log level 35 | 36 | - (ARTLogLevel)logLevel { 37 | return self.logger.logLevel; 38 | } 39 | 40 | - (void)setLogLevel:(ARTLogLevel)logLevel { 41 | self.logger.logLevel = logLevel; 42 | } 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /Source/SocketRocket/NSURLRequest+ARTSRWebSocket.m: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2012 Square Inc. 3 | // Portions Copyright (c) 2016-present, Facebook, Inc. 4 | // 5 | // All rights reserved. 6 | // 7 | // This source code is licensed under the BSD-style license found in the 8 | // LICENSE file in the root directory of this source tree. An additional grant 9 | // of patent rights can be found in the PATENTS file in the same directory. 10 | // 11 | 12 | #import "NSURLRequest+ARTSRWebSocket.h" 13 | #import "NSURLRequest+ARTSRWebSocketPrivate.h" 14 | 15 | // Required for object file to always be linked. 16 | void import_NSURLRequest_ARTSRWebSocket(void) { } 17 | 18 | NS_ASSUME_NONNULL_BEGIN 19 | 20 | static NSString *const ARTSRSSLPinnnedCertificatesKey = @"SocketRocket_SSLPinnedCertificates"; 21 | 22 | @implementation NSURLRequest (ARTSRWebSocket) 23 | 24 | - (nullable NSArray *)ARTSR_SSLPinnedCertificates 25 | { 26 | return nil; 27 | } 28 | 29 | @end 30 | 31 | @implementation NSMutableURLRequest (ARTSRWebSocket) 32 | 33 | - (void)setARTSR_SSLPinnedCertificates:(nullable NSArray *)ARTSR_SSLPinnedCertificates 34 | { 35 | [NSException raise:NSInvalidArgumentException 36 | format:@"Using pinned certificates is neither secure nor supported in SocketRocket, " 37 | "and leads to security issues. Please use a proper, trust chain validated certificate."]; 38 | } 39 | 40 | @end 41 | 42 | NS_ASSUME_NONNULL_END 43 | -------------------------------------------------------------------------------- /Source/ARTBackoffRetryDelayCalculator.m: -------------------------------------------------------------------------------- 1 | #import "ARTBackoffRetryDelayCalculator.h" 2 | #import "ARTJitterCoefficientGenerator.h" 3 | 4 | NS_ASSUME_NONNULL_BEGIN 5 | 6 | @interface ARTBackoffRetryDelayCalculator () 7 | 8 | @property (nonatomic, readonly) NSTimeInterval initialRetryTimeout; 9 | @property (nonatomic, readonly) id jitterCoefficientGenerator; 10 | 11 | @end 12 | 13 | NS_ASSUME_NONNULL_END 14 | 15 | @implementation ARTBackoffRetryDelayCalculator 16 | 17 | - (instancetype)initWithInitialRetryTimeout:(NSTimeInterval)initialRetryTimeout 18 | jitterCoefficientGenerator:(id)jitterCoefficientGenerator { 19 | if (self = [super init]) { 20 | _initialRetryTimeout = initialRetryTimeout; 21 | _jitterCoefficientGenerator = jitterCoefficientGenerator; 22 | } 23 | 24 | return self; 25 | } 26 | 27 | - (NSTimeInterval)delayForRetryNumber:(NSInteger)retryNumber { 28 | const double backoffCoefficient = [ARTBackoffRetryDelayCalculator backoffCoefficientForRetryNumber:retryNumber]; 29 | const double jitterCoefficient = [self.jitterCoefficientGenerator generateJitterCoefficient]; 30 | 31 | return self.initialRetryTimeout * backoffCoefficient * jitterCoefficient; 32 | } 33 | 34 | + (double)backoffCoefficientForRetryNumber:(NSInteger)retryNumber { 35 | return MIN((NSTimeInterval)(retryNumber + 2.0) / 3.0, 2.0); 36 | } 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /Source/ARTChannelOptions.m: -------------------------------------------------------------------------------- 1 | #import "ARTChannelOptions.h" 2 | #import "ARTChannelOptions+Private.h" 3 | #import "ARTEncoder.h" 4 | 5 | @implementation ARTChannelOptions { 6 | ARTCipherParams *_cipher; 7 | } 8 | 9 | - (instancetype)initWithCipher:(id)cipherParams { 10 | if (self = [super init]) { 11 | self->_cipher = [cipherParams toCipherParams]; 12 | } 13 | return self; 14 | } 15 | 16 | - (instancetype)initWithCipherKey:(id)key { 17 | return [self initWithCipher:@{@"key": key}]; 18 | } 19 | 20 | - (id)copyWithZone:(NSZone *)zone { 21 | ARTChannelOptions *copied = [[[self class] alloc] init]; 22 | 23 | // The _frozen flag prevents the instance we were copying from being mutated, but we don't yet want to prevent the new instance from being mutated 24 | copied->_frozen = NO; 25 | 26 | copied->_cipher = _cipher; 27 | 28 | return copied; 29 | } 30 | 31 | - (ARTCipherParams *)cipher { 32 | return _cipher; 33 | } 34 | 35 | - (void)setCipher:(ARTCipherParams *)cipher { 36 | if (self.isFrozen) { 37 | @throw [NSException exceptionWithName:NSObjectInaccessibleException 38 | reason:[NSString stringWithFormat:@"%@: You can't change options after you've passed it to receiver.", self.class] 39 | userInfo:nil]; 40 | } 41 | _cipher = cipher; 42 | } 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /Source/SocketRocket/Internal/Utilities/ARTSRHash.m: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2016-present, Facebook, Inc. 3 | // All rights reserved. 4 | // 5 | // This source code is licensed under the BSD-style license found in the 6 | // LICENSE file in the root directory of this source tree. An additional grant 7 | // of patent rights can be found in the PATENTS file in the same directory. 8 | // 9 | 10 | #import "ARTSRHash.h" 11 | 12 | #import 13 | 14 | NS_ASSUME_NONNULL_BEGIN 15 | 16 | NSData *ARTSRSHA1HashFromString(NSString *string) 17 | { 18 | size_t length = [string lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; 19 | return ARTSRSHA1HashFromBytes(string.UTF8String, length); 20 | } 21 | 22 | NSData *ARTSRSHA1HashFromBytes(const char *bytes, size_t length) 23 | { 24 | uint8_t outputLength = CC_SHA1_DIGEST_LENGTH; 25 | unsigned char output[outputLength]; 26 | CC_SHA1(bytes, (CC_LONG)length, output); 27 | 28 | return [NSData dataWithBytes:output length:outputLength]; 29 | } 30 | 31 | NSString *ARTSRBase64EncodedStringFromData(NSData *data) 32 | { 33 | if ([data respondsToSelector:@selector(base64EncodedStringWithOptions:)]) { 34 | return [data base64EncodedStringWithOptions:0]; 35 | } 36 | 37 | #pragma clang diagnostic push 38 | #pragma clang diagnostic ignored "-Wdeprecated-declarations" 39 | return [data base64Encoding]; 40 | #pragma clang diagnostic pop 41 | } 42 | 43 | NS_ASSUME_NONNULL_END 44 | -------------------------------------------------------------------------------- /Ably.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = "Ably" 3 | s.version = `Scripts/get-version.sh` 4 | s.summary = "iOS, tvOS and macOS Objective-C and Swift client for Ably" 5 | s.description = <<-DESC 6 | iOS, tvOS and macOS Objective-C and Swift client library for ably.com, the realtime messaging service. 7 | DESC 8 | s.homepage = "https://www.ably.com" 9 | s.license = { :type => 'Apache 2.0', :file => 'LICENSE' } 10 | s.author = { "Ably" => "support@ably.com" } 11 | s.source = { :git => "https://github.com/ably/ably-cocoa.git", :tag => s.version.to_s } 12 | s.social_media_url = 'https://twitter.com/ablyrealtime' 13 | s.documentation_url = "https://www.ably.io/documentation" 14 | s.ios.deployment_target = '10.0' 15 | s.tvos.deployment_target = '10.0' 16 | s.osx.deployment_target = '10.12' 17 | s.requires_arc = true 18 | s.swift_version = '5.0' 19 | s.source_files = 'Source/**/*.{h,m,swift}' 20 | s.resource_bundles = {'Ably' => ['Source/PrivacyInfo.xcprivacy']} 21 | s.private_header_files = 'Source/PrivateHeaders/**/*.h', 'Source/SocketRocket/**/*.h' 22 | s.module_map = 'Source/Ably.modulemap' 23 | s.dependency 'msgpack', '0.4.0' 24 | s.dependency 'AblyDeltaCodec', '1.3.3' 25 | end 26 | -------------------------------------------------------------------------------- /.github/workflows/docs.yml: -------------------------------------------------------------------------------- 1 | name: Docs Generation 2 | 3 | on: 4 | pull_request: 5 | push: 6 | branches: 7 | - main 8 | tags: 9 | - '*' 10 | 11 | jobs: 12 | build: 13 | runs-on: macos-15 14 | 15 | permissions: 16 | deployments: write 17 | id-token: write 18 | 19 | steps: 20 | - uses: actions/checkout@v2 21 | 22 | - name: Select Specific Xcode Version (16.4) 23 | run: | 24 | sudo xcode-select -s /Applications/Xcode_16.4.app 25 | echo "Selected Xcode version:" 26 | xcodebuild -version 27 | 28 | - name: Install Dependencies 29 | run: | 30 | make submodules 31 | bundle install 32 | make update_carthage_dependencies_macos 33 | 34 | - name: Build Documentation 35 | run: | 36 | ./Scripts/jazzy.sh 37 | ls -al Docs/jazzy 38 | 39 | - name: Configure AWS Credentials 40 | uses: aws-actions/configure-aws-credentials@v1 41 | with: 42 | aws-region: eu-west-2 43 | role-to-assume: arn:aws:iam::${{ secrets.ABLY_AWS_ACCOUNT_ID_SDK }}:role/ably-sdk-builds-ably-cocoa 44 | role-session-name: "${{ github.run_id }}-${{ github.run_number }}" 45 | 46 | - name: Upload Documentation 47 | uses: ably/sdk-upload-action@v1 48 | with: 49 | sourcePath: Docs/jazzy 50 | githubToken: ${{ secrets.GITHUB_TOKEN }} 51 | artifactName: jazzydoc 52 | 53 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTPushChannelSubscriptions+Private.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import "ARTQueuedDealloc.h" 3 | 4 | @class ARTRestInternal; 5 | @class ARTInternalLog; 6 | 7 | NS_ASSUME_NONNULL_BEGIN 8 | 9 | @interface ARTPushChannelSubscriptionsInternal : NSObject 10 | 11 | - (instancetype)initWithRest:(ARTRestInternal *)rest logger:(ARTInternalLog *)logger; 12 | 13 | - (void)save:(ARTPushChannelSubscription *)channelSubscription wrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents callback:(ARTCallback)callback; 14 | 15 | - (void)listChannelsWithWrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents completion:(ARTPaginatedTextCallback)callback; 16 | 17 | - (void)list:(NSStringDictionary *)params wrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents callback:(ARTPaginatedPushChannelCallback)callback; 18 | 19 | - (void)remove:(ARTPushChannelSubscription *)subscription wrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents callback:(ARTCallback)callback; 20 | 21 | - (void)removeWhere:(NSStringDictionary *)params wrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents callback:(ARTCallback)callback; 22 | 23 | @end 24 | 25 | @interface ARTPushChannelSubscriptions () 26 | 27 | @property (nonatomic, readonly) ARTPushChannelSubscriptionsInternal *internal; 28 | 29 | - (instancetype)initWithInternal:(ARTPushChannelSubscriptionsInternal *)internal queuedDealloc:(ARTQueuedDealloc *)dealloc; 30 | 31 | @end 32 | 33 | NS_ASSUME_NONNULL_END 34 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTWebSocketTransport+Private.h: -------------------------------------------------------------------------------- 1 | #import "ARTWebSocketTransport.h" 2 | #import "ARTSRWebSocket.h" 3 | #import "ARTEncoder.h" 4 | #import 5 | #import "ARTWebSocket.h" 6 | 7 | NS_ASSUME_NONNULL_BEGIN 8 | 9 | @interface ARTWebSocketTransport () 10 | 11 | // From RestClient 12 | @property (readwrite, nonatomic) id encoder; 13 | @property (readonly, nonatomic) ARTInternalLog *logger; 14 | @property (readonly, nonatomic) ARTClientOptions *options; 15 | 16 | @property (readwrite, nonatomic, nullable) id websocket; 17 | @property (readwrite, nonatomic, nullable) NSURL *websocketURL; 18 | 19 | - (NSURL *)setupWebSocket:(NSDictionary *)params withOptions:(ARTClientOptions *)options resumeKey:(NSString *_Nullable)resumeKey; 20 | 21 | - (void)setState:(ARTRealtimeTransportState)state; 22 | 23 | /// This is called as a result of a call to `-connectWithToken:` or `-connectWithKey:`. It calls (asynchronously on a queue internal to this transport) `-open` on the underlying `ARTWebSocket`. 24 | /// 25 | /// Exposed so that test subclasses can override and replace or wrap in additional logic. 26 | - (void)openWebSocket; 27 | 28 | @end 29 | 30 | #pragma mark - ARTEvent 31 | 32 | @interface ARTEvent (TransportState) 33 | - (instancetype)initWithTransportState:(ARTRealtimeTransportState)value; 34 | + (instancetype)newWithTransportState:(ARTRealtimeTransportState)value; 35 | 36 | @end 37 | 38 | NS_ASSUME_NONNULL_END 39 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTPushDeviceRegistrations+Private.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import "ARTQueuedDealloc.h" 3 | 4 | @class ARTRestInternal; 5 | @class ARTInternalLog; 6 | 7 | NS_ASSUME_NONNULL_BEGIN 8 | 9 | @interface ARTPushDeviceRegistrationsInternal : NSObject 10 | 11 | - (instancetype)initWithRest:(ARTRestInternal *)rest logger:(ARTInternalLog *)logger; 12 | 13 | - (void)save:(ARTDeviceDetails *)deviceDetails wrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents callback:(ARTCallback)callback; 14 | 15 | - (void)get:(ARTDeviceId *)deviceId wrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents callback:(void (^)(ARTDeviceDetails *_Nullable, ARTErrorInfo *_Nullable))callback; 16 | 17 | - (void)list:(NSStringDictionary *)params wrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents callback:(ARTPaginatedDeviceDetailsCallback)callback; 18 | 19 | - (void)remove:(NSString *)deviceId wrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents callback:(ARTCallback)callback; 20 | 21 | - (void)removeWhere:(NSStringDictionary *)params wrapperSDKAgents:(nullable NSStringDictionary *)wrapperSDKAgents callback:(ARTCallback)callback; 22 | 23 | @end 24 | 25 | @interface ARTPushDeviceRegistrations () 26 | 27 | @property (nonatomic, readonly) ARTPushDeviceRegistrationsInternal *internal; 28 | 29 | - (instancetype)initWithInternal:(ARTPushDeviceRegistrationsInternal *)internal queuedDealloc:(ARTQueuedDealloc *)dealloc; 30 | 31 | @end 32 | 33 | NS_ASSUME_NONNULL_END 34 | -------------------------------------------------------------------------------- /Source/SocketRocket/NSURLRequest+ARTSRWebSocket.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2012 Square Inc. 3 | // Portions Copyright (c) 2016-present, Facebook, Inc. 4 | // 5 | // All rights reserved. 6 | // 7 | // This source code is licensed under the BSD-style license found in the 8 | // LICENSE file in the root directory of this source tree. An additional grant 9 | // of patent rights can be found in the PATENTS file in the same directory. 10 | // 11 | 12 | #import 13 | 14 | NS_ASSUME_NONNULL_BEGIN 15 | 16 | @interface NSURLRequest (ARTSRWebSocket) 17 | 18 | /** 19 | An array of pinned `SecCertificateRef` SSL certificates that `ARTSRWebSocket` will use for validation. 20 | */ 21 | @property (nullable, nonatomic, copy, readonly) NSArray *ARTSR_SSLPinnedCertificates 22 | DEPRECATED_MSG_ATTRIBUTE("Using pinned certificates is neither secure nor supported in SocketRocket, " 23 | "and leads to security issues. Please use a proper, trust chain validated certificate."); 24 | 25 | @end 26 | 27 | @interface NSMutableURLRequest (ARTSRWebSocket) 28 | 29 | /** 30 | An array of pinned `SecCertificateRef` SSL certificates that `ARTSRWebSocket` will use for validation. 31 | */ 32 | @property (nullable, nonatomic, copy) NSArray *ARTSR_SSLPinnedCertificates 33 | DEPRECATED_MSG_ATTRIBUTE("Using pinned certificates is neither secure nor supported in SocketRocket, " 34 | "and leads to security issues. Please use a proper, trust chain validated certificate."); 35 | 36 | @end 37 | 38 | NS_ASSUME_NONNULL_END 39 | -------------------------------------------------------------------------------- /Source/include/Ably/ARTPushAdmin.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import 4 | #import 5 | 6 | NS_ASSUME_NONNULL_BEGIN 7 | 8 | /** 9 | The protocol upon which the `ARTPushAdmin` is implemented. 10 | */ 11 | @protocol ARTPushAdminProtocol 12 | 13 | /// :nodoc: 14 | - (instancetype)init NS_UNAVAILABLE; 15 | 16 | /** 17 | * Sends a push notification directly to a device, or a group of devices sharing the same `clientId`. 18 | * 19 | * @param recipient A JSON object containing the recipient details using `clientId`, `deviceId` or the underlying notifications service. 20 | * @param data A JSON object containing the push notification payload. 21 | * @param callback A success or failure callback function. 22 | */ 23 | - (void)publish:(ARTPushRecipient *)recipient data:(ARTJsonObject *)data callback:(nullable ARTCallback)callback; 24 | 25 | @end 26 | 27 | /** 28 | * Enables the management of device registrations and push notification subscriptions. Also enables the publishing of push notifications to devices. 29 | */ 30 | NS_SWIFT_SENDABLE 31 | @interface ARTPushAdmin : NSObject 32 | 33 | /** 34 | * An `ARTPushDeviceRegistrations` object. 35 | */ 36 | @property (nonatomic, readonly) ARTPushDeviceRegistrations *deviceRegistrations; 37 | 38 | /** 39 | * An `ARTPushChannelSubscriptions` object. 40 | */ 41 | @property (nonatomic, readonly) ARTPushChannelSubscriptions *channelSubscriptions; 42 | 43 | @end 44 | 45 | NS_ASSUME_NONNULL_END 46 | -------------------------------------------------------------------------------- /Source/PrivateHeaders/Ably/ARTCrypto+Private.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @class ARTInternalLog; 4 | 5 | NS_ASSUME_NONNULL_BEGIN 6 | 7 | @interface ARTCipherParams () 8 | 9 | @property (readonly, nonatomic, nullable) NSData *iv; 10 | - (instancetype)initWithAlgorithm:(NSString *)algorithm key:(id)key iv:(NSData *_Nullable)iv; 11 | 12 | @end 13 | 14 | @protocol ARTChannelCipher 15 | 16 | - (ARTStatus *)encrypt:(NSData *)plaintext output:(NSData *_Nullable *_Nullable)output; 17 | - (ARTStatus *)decrypt:(NSData *)ciphertext output:(NSData *_Nullable *_Nullable)output; 18 | - (nullable NSString *)cipherName; 19 | - (size_t) keyLength; 20 | 21 | @end 22 | 23 | @interface ARTCbcCipher : NSObject 24 | 25 | - (id)initWithCipherParams:(ARTCipherParams *)cipherParams logger:(ARTInternalLog *)logger; 26 | + (instancetype)cbcCipherWithParams:(ARTCipherParams *)cipherParams logger:(ARTInternalLog *)logger; 27 | 28 | 29 | @property (nonatomic) ARTInternalLog *logger; 30 | @property (readonly, nonatomic) NSData *keySpec; 31 | @property NSData *iv; 32 | @property (readonly) NSUInteger blockLength; 33 | 34 | @end 35 | 36 | @interface ARTCrypto () 37 | 38 | + (NSString *)defaultAlgorithm; 39 | + (int)defaultKeyLength; 40 | + (int)defaultBlockLength; 41 | 42 | + (nullable NSMutableData *)generateSecureRandomData:(size_t)length; 43 | + (NSData *)generateHashSHA256:(NSData *)data; 44 | 45 | + (id)cipherWithParams:(ARTCipherParams *)params logger:(ARTInternalLog *)logger; 46 | 47 | @end 48 | 49 | NS_ASSUME_NONNULL_END 50 | --------------------------------------------------------------------------------