diff --git a/.pubnub.yml b/.pubnub.yml
index 713c8be0b..86fde73e7 100644
--- a/.pubnub.yml
+++ b/.pubnub.yml
@@ -1,9 +1,16 @@
---
name: objective-c
scm: github.com/pubnub/objective-c
-version: "5.6.0"
+version: "5.6.1"
schema: 1
changelog:
+ - date: 2024-07-08
+ version: v5.6.1
+ changes:
+ - type: bug
+ text: "Fix issue because of which wrong request timeout has been used."
+ - type: bug
+ text: "Fix issue with `PNSubscribeCursorData` which should have an optional `region` to handle user timetoken in received real-time messages."
- date: 2024-06-27
version: v5.6.0
changes:
@@ -1358,7 +1365,7 @@ sdks:
- distribution-type: source
distribution-repository: GitHub release
package-name: PubNub.framework
- location: https://github.com/pubnub/objective-c/archive/refs/tags/v5.6.0.zip
+ location: https://github.com/pubnub/objective-c/archive/refs/tags/v5.6.1.zip
supported-platforms:
supported-operating-systems:
macOS:
@@ -1419,7 +1426,7 @@ sdks:
- distribution-type: library
distribution-repository: GitHub release
package-name: PubNub.ios.xcframework.tar.gz
- location: https://github.com/pubnub/objective-c/releases/download/v5.6.0/PubNub.ios.xcframework.tar.gz
+ location: https://github.com/pubnub/objective-c/releases/download/v5.6.1/PubNub.ios.xcframework.tar.gz
supported-platforms:
supported-operating-systems:
iOS:
@@ -1438,7 +1445,7 @@ sdks:
- distribution-type: library
distribution-repository: GitHub release
package-name: PubNub.macos.framework.tar.gz
- location: https://github.com/pubnub/objective-c/releases/download/v5.6.0/PubNub.macos.framework.tar.gz
+ location: https://github.com/pubnub/objective-c/releases/download/v5.6.1/PubNub.macos.framework.tar.gz
supported-platforms:
supported-operating-systems:
macOS:
@@ -1454,7 +1461,7 @@ sdks:
- distribution-type: library
distribution-repository: GitHub release
package-name: PubNub.tvos.xcframework.tar.gz
- location: https://github.com/pubnub/objective-c/releases/download/v5.6.0/PubNub.tvos.xcframework.tar.gz
+ location: https://github.com/pubnub/objective-c/releases/download/v5.6.1/PubNub.tvos.xcframework.tar.gz
supported-platforms:
supported-operating-systems:
tvOS:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9e006701b..615fb6ed9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,10 @@
+## v5.6.1
+July 08 2024
+
+#### Fixed
+- Fix issue because of which wrong request timeout has been used.
+- Fix issue with `PNSubscribeCursorData` which should have an optional `region` to handle user timetoken in received real-time messages.
+
## v5.6.0
June 27 2024
diff --git a/Example/PubNub/PNAppDelegate.m b/Example/PubNub/PNAppDelegate.m
index 2052ff1e2..0e5054740 100644
--- a/Example/PubNub/PNAppDelegate.m
+++ b/Example/PubNub/PNAppDelegate.m
@@ -595,10 +595,8 @@ - (void)handleErrorStatus:(PNErrorStatus *)status {
NSLog(@"Decryption error. Be sure the data is encrypted and/or encrypted with the correct cipher key.");
NSLog(@"You can find the raw data returned from the server in the status.data attribute: %@", status.associatedObject);
if (status.operation == PNSubscribeOperation) {
-
- NSLog(@"Decryption failed for message from channel: %@\nmessage: %@",
- ((PNMessageData *)status.associatedObject).channel,
- ((PNMessageData *)status.associatedObject).message);
+ PNSubscribeMessageEventData *data = status.associatedObject;
+ NSLog(@"Decryption failed for message from channel: %@\nmessage: %@", data.channel, data.message);
}
}
else if (status.category == PNMalformedFilterExpressionCategory) {
diff --git a/Framework/PubNub/Info.plist b/Framework/PubNub/Info.plist
index 9eb76a905..de50bfee2 100644
--- a/Framework/PubNub/Info.plist
+++ b/Framework/PubNub/Info.plist
@@ -7,7 +7,7 @@
CFBundleExecutable
PubNub
CFBundleGetInfoString
- 5.6.0
+ 5.6.1
CFBundleIdentifier
com.pubnub.pubnub-objc
CFBundleInfoDictionaryVersion
@@ -17,11 +17,11 @@
CFBundlePackageType
FMWK
CFBundleShortVersionString
- 5.6.0
+ 5.6.1
CFBundleSignature
????
CFBundleVersion
- 5.6.0
+ 5.6.1
NSHumanReadableCopyright
© 2010 - 2020 PubNub, Inc.
NSPrincipalClass
diff --git a/Framework/PubNub/PubNub-iOS-Info.plist b/Framework/PubNub/PubNub-iOS-Info.plist
index 9eb76a905..de50bfee2 100644
--- a/Framework/PubNub/PubNub-iOS-Info.plist
+++ b/Framework/PubNub/PubNub-iOS-Info.plist
@@ -7,7 +7,7 @@
CFBundleExecutable
PubNub
CFBundleGetInfoString
- 5.6.0
+ 5.6.1
CFBundleIdentifier
com.pubnub.pubnub-objc
CFBundleInfoDictionaryVersion
@@ -17,11 +17,11 @@
CFBundlePackageType
FMWK
CFBundleShortVersionString
- 5.6.0
+ 5.6.1
CFBundleSignature
????
CFBundleVersion
- 5.6.0
+ 5.6.1
NSHumanReadableCopyright
© 2010 - 2020 PubNub, Inc.
NSPrincipalClass
diff --git a/Framework/PubNub/PubNub-tvOS-Info.plist b/Framework/PubNub/PubNub-tvOS-Info.plist
index 9eb76a905..de50bfee2 100644
--- a/Framework/PubNub/PubNub-tvOS-Info.plist
+++ b/Framework/PubNub/PubNub-tvOS-Info.plist
@@ -7,7 +7,7 @@
CFBundleExecutable
PubNub
CFBundleGetInfoString
- 5.6.0
+ 5.6.1
CFBundleIdentifier
com.pubnub.pubnub-objc
CFBundleInfoDictionaryVersion
@@ -17,11 +17,11 @@
CFBundlePackageType
FMWK
CFBundleShortVersionString
- 5.6.0
+ 5.6.1
CFBundleSignature
????
CFBundleVersion
- 5.6.0
+ 5.6.1
NSHumanReadableCopyright
© 2010 - 2020 PubNub, Inc.
NSPrincipalClass
diff --git a/Framework/PubNub/PubNub-watchOS-Info.plist b/Framework/PubNub/PubNub-watchOS-Info.plist
index 9eb76a905..de50bfee2 100644
--- a/Framework/PubNub/PubNub-watchOS-Info.plist
+++ b/Framework/PubNub/PubNub-watchOS-Info.plist
@@ -7,7 +7,7 @@
CFBundleExecutable
PubNub
CFBundleGetInfoString
- 5.6.0
+ 5.6.1
CFBundleIdentifier
com.pubnub.pubnub-objc
CFBundleInfoDictionaryVersion
@@ -17,11 +17,11 @@
CFBundlePackageType
FMWK
CFBundleShortVersionString
- 5.6.0
+ 5.6.1
CFBundleSignature
????
CFBundleVersion
- 5.6.0
+ 5.6.1
NSHumanReadableCopyright
© 2010 - 2020 PubNub, Inc.
NSPrincipalClass
diff --git a/PubNub.podspec b/PubNub.podspec
index 7aedc894d..1a65c0cea 100644
--- a/PubNub.podspec
+++ b/PubNub.podspec
@@ -9,7 +9,7 @@
Pod::Spec.new do |spec|
spec.name = 'PubNub'
- spec.version = '5.6.0'
+ spec.version = '5.6.1'
spec.summary = 'The PubNub Real-Time Network. Build real-time apps quickly and scale them globally.'
spec.homepage = 'https://github.com/pubnub/objective-c'
diff --git a/PubNub/Data/Managers/PNSubscriber.m b/PubNub/Data/Managers/PNSubscriber.m
index e81a5503c..6e5121b99 100644
--- a/PubNub/Data/Managers/PNSubscriber.m
+++ b/PubNub/Data/Managers/PNSubscriber.m
@@ -1336,7 +1336,7 @@ - (void)handleNewMessage:(PNMessageResult *)message {
PNErrorStatus *status = nil;
- PNLogResult(self.client.logger, @" %@", [message stringifiedRepresentationWithSerializer:nil]);
+ PNLogResult(self.client.logger, @" %@", [message stringifiedRepresentationWithSerializer:self.client.coder]);
if (message.data.decryptionError) {
status = [PNErrorStatus objectWithOperation:PNSubscribeOperation
@@ -1352,7 +1352,7 @@ - (void)handleNewMessage:(PNMessageResult *)message {
- (void)handleNewSignal:(PNSignalResult *)signal {
if (!signal) return;
- PNLogResult(self.client.logger, @" %@", [signal stringifiedRepresentationWithSerializer:nil]);
+ PNLogResult(self.client.logger, @" %@", [signal stringifiedRepresentationWithSerializer:self.client.coder]);
[self.client.listenersManager notifySignal:signal];
}
@@ -1360,7 +1360,7 @@ - (void)handleNewSignal:(PNSignalResult *)signal {
- (void)handleNewMessageAction:(PNMessageActionResult *)action {
if (!action) return;
- PNLogResult(self.client.logger, @" %@", [action stringifiedRepresentationWithSerializer:nil]);
+ PNLogResult(self.client.logger, @" %@", [action stringifiedRepresentationWithSerializer:self.client.coder]);
[self.client.listenersManager notifyMessageAction:action];
}
@@ -1368,7 +1368,7 @@ - (void)handleNewMessageAction:(PNMessageActionResult *)action {
- (void)handleNewObjectsEvent:(PNObjectEventResult *)object {
if (!object) return;
- PNLogResult(self.client.logger, @" %@", [object stringifiedRepresentationWithSerializer:nil]);
+ PNLogResult(self.client.logger, @" %@", [object stringifiedRepresentationWithSerializer:self.client.coder]);
[self.client.listenersManager notifyObjectEvent:object];
}
@@ -1377,8 +1377,8 @@ - (void)handleNewFileEvent:(PNFileEventResult *)file {
PNErrorStatus *status = nil;
if (file) {
- PNLogResult(self.client.logger, @" %@", [file stringifiedRepresentationWithSerializer:nil]);
-
+ PNLogResult(self.client.logger, @" %@", [file stringifiedRepresentationWithSerializer:self.client.coder]);
+
if (file.data.decryptionError) {
status = [PNErrorStatus objectWithOperation:PNSubscribeOperation
category:PNDecryptionErrorCategory
@@ -1398,7 +1398,7 @@ - (void)handleNewFileEvent:(PNFileEventResult *)file {
- (void)handleNewPresenceEvent:(PNPresenceEventResult *)presence {
if (presence) {
- PNLogResult(self.client.logger, @" %@", [presence stringifiedRepresentationWithSerializer:nil]);
+ PNLogResult(self.client.logger, @" %@", [presence stringifiedRepresentationWithSerializer:self.client.coder]);
}
[self.client.listenersManager notifyPresenceEvent:presence];
diff --git a/PubNub/Data/Service Objects/PNOperationResult.m b/PubNub/Data/Service Objects/PNOperationResult.m
index 93c742d2d..d5d0302d6 100644
--- a/PubNub/Data/Service Objects/PNOperationResult.m
+++ b/PubNub/Data/Service Objects/PNOperationResult.m
@@ -118,7 +118,7 @@ - (id)copyWithZone:(NSZone *)zone {
- (NSDictionary *)dictionaryRepresentationWithSerializer:(id)serializer {
id processedData = self.responseData;
- if (serializer) {
+ if (serializer && processedData) {
NSError *err;
NSData *serializedData = [serializer dataOfClass:[NSDictionary class] fromObject:processedData withError:&err];
NSDictionary *serializedDictionary = [serializer.jsonSerializer JSONObjectWithData:serializedData error:&err];
@@ -128,7 +128,7 @@ - (NSDictionary *)dictionaryRepresentationWithSerializer:(id
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
NSMutableDictionary *response = [@{
@"Status code": @(self.statusCode),
- @"Processed data": processedData
+ @"Processed data": processedData ?: @"no data"
} mutableCopy];
return @{@"Operation": PNOperationTypeStrings[self.operation],
diff --git a/PubNub/Misc/PNConstants.h b/PubNub/Misc/PNConstants.h
index 058e136b0..ae0eaecb3 100644
--- a/PubNub/Misc/PNConstants.h
+++ b/PubNub/Misc/PNConstants.h
@@ -15,7 +15,7 @@
#pragma mark General information constants
// Stores client library version number
-static NSString * const kPNLibraryVersion = @"5.6.0";
+static NSString * const kPNLibraryVersion = @"5.6.1";
// Stores information about SDK codebase
static NSString * const kPNCommit = @"fd5c7ed678527fce07eaf7eb162935caf1bfd303";
diff --git a/PubNub/Modules/Transport/PNURLSessionTransport.m b/PubNub/Modules/Transport/PNURLSessionTransport.m
index 92bf0b844..ac3de59f0 100644
--- a/PubNub/Modules/Transport/PNURLSessionTransport.m
+++ b/PubNub/Modules/Transport/PNURLSessionTransport.m
@@ -165,8 +165,8 @@ - (void)setupWithConfiguration:(PNTransportConfiguration *)configuration {
- (void)requestsWithBlock:(void (^)(NSArray *))block {
if (!block) return;
-
- [self.lock syncWriteAccessWithBlock:^{
+
+ [self.lock writeAccessWithBlock:^{
block(self.requests);
// Filter out potentially cancelled requests after block has been called.
[self.requests filterUsingPredicate:self.cancelledPredicate];
@@ -182,20 +182,26 @@ - (void)sendRequest:(PNTransportRequest *)request withCompletionBlock:(PNRequest
PNWeakify(self);
__block NSURLSessionTask *task;
- task = [self.session dataTaskWithRequest:urlRequest
- completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
+ __block NSURLSession *session;
+
+ [self.lock readAccessWithBlock:^{
+ session = self.session;
+ }];
+
+ task = [session dataTaskWithRequest:urlRequest
+ completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
PNStrongify(self);
BOOL retriableError = error && error.code != NSURLErrorCancelled;
NSInteger statusCode = ((NSHTTPURLResponse *)response).statusCode;
BOOL retriableStatusCode = statusCode >= 400 && statusCode != 403;
NSTimeInterval delay = 0.f;
- if ((retriableError || retriableStatusCode) && request.retriable) {
+ if ((retriableError || retriableStatusCode) && request.retriable && !request.cancelled) {
PNRequestRetryConfiguration *retry = self.configuration.retryConfiguration;
NSUInteger retryAttempt = request.retryAttempt + 1;
delay = [retry retryDelayForFailedRequest:urlRequest withResponse:response retryAttempt:retryAttempt];
}
-
+
if (delay > 0.f) {
request.retryAttempt += 1;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delay * NSEC_PER_SEC)),
@@ -219,15 +225,21 @@ - (void)sendDownloadRequest:(PNTransportRequest *)request withCompletionBlock:(P
PNWeakify(self);
__block NSURLSessionTask *task;
- task = [self.session downloadTaskWithRequest:urlRequest
- completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) {
+ __block NSURLSession *session;
+
+ [self.lock readAccessWithBlock:^{
+ session = self.session;
+ }];
+
+ task = [session downloadTaskWithRequest:urlRequest
+ completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) {
PNStrongify(self);
BOOL retriableError = error && error.code != NSURLErrorCancelled;
NSInteger statusCode = ((NSHTTPURLResponse *)response).statusCode;
BOOL retriableStatusCode = statusCode >= 400 && statusCode != 403;
NSTimeInterval delay = 0.f;
- if ((retriableError || retriableStatusCode) && request.retriable) {
+ if ((retriableError || retriableStatusCode) && request.retriable && !request.cancelled) {
PNRequestRetryConfiguration *retry = self.configuration.retryConfiguration;
NSUInteger retryAttempt = request.retryAttempt + 1;
delay = [retry retryDelayForFailedRequest:urlRequest withResponse:response retryAttempt:retryAttempt];
@@ -252,31 +264,38 @@ - (void)sendDownloadRequest:(PNTransportRequest *)request withCompletionBlock:(P
}
- (void)sendRequest:(PNTransportRequest *)request withSessionTask:(NSURLSessionTask *)task {
- [self.lock asyncWriteAccessWithBlock:^{
- [self.requests addObject:request];
+ if (request.cancellable) {
+ [self.lock writeAccessWithBlock:^{
+ [self.requests addObject:request];
+ }];
- PNLogRequest(self.configuration.logger, @" %@ %@",
- request.stringifiedMethod, task.originalRequest.URL.absoluteString);
-
- if (request.cancellable) {
- __weak __typeof(request) weakRequest = request;
- PNWeakify(self);
-
- request.cancel = ^{
- PNStrongify(self);
-
- weakRequest.cancelled = YES;
- weakRequest.cancel = nil;
- [task cancel];
-
- [self.lock asyncWriteAccessWithBlock:^{
- [self.requests removeObject:weakRequest];
- }];
- };
- }
+ __weak __typeof(request) weakRequest = request;
+ PNWeakify(self);
- [task resume];
- }];
+ request.cancel = ^{
+ NSURLSessionTaskState taskState = task.state;
+ BOOL cancelled = weakRequest.cancelled;
+
+ PNStrongify(self);
+
+ weakRequest.cancelled = YES;
+ weakRequest.cancel = nil;
+
+ if (cancelled || taskState != NSURLSessionTaskStateRunning) return;
+
+ [task cancel];
+
+ [self.lock writeAccessWithBlock:^{
+ __strong __typeof__(weakRequest) strongRequest = weakRequest;
+ if (strongRequest) [self.requests removeObject:strongRequest];
+ }];
+ };
+ }
+
+ PNLogRequest(self.configuration.logger, @" %@ %@",
+ request.stringifiedMethod, task.originalRequest.URL.absoluteString);
+
+ [task resume];
}
- (PNTransportRequest *)transportRequestFromTransportRequest:(PNTransportRequest *)request {
@@ -302,7 +321,7 @@ - (PNTransportRequest *)transportRequestFromTransportRequest:(PNTransportRequest
taskCompletion:(NSURLSessionTask *)task
withResponse:(NSURLResponse *)response
data:(NSData *)data {
- [self.lock syncWriteAccessWithBlock:^{
+ [self.lock writeAccessWithBlock:^{
request.cancel = nil;
[self.requests removeObject:request];
NSUInteger activeRequestsCount = self.requests.count;
@@ -362,7 +381,7 @@ - (void)endBackgroundTasksCompletionIfRequired {
}
- (void)invalidate {
- [self.lock syncWriteAccessWithBlock:^{
+ [self.lock writeAccessWithBlock:^{
[self endBackgroundTasksCompletionIfRequired];
[self.session invalidateAndCancel];
self->_session = nil;
@@ -380,10 +399,10 @@ - (void)setupURLSession {
}
- (NSURLSessionConfiguration *)urlSessionConfiguration {
- NSString *identifier = [NSString stringWithFormat:@"com.pubnub.network.%p", self];
+ self.identifier = [NSString stringWithFormat:@"com.pubnub.transport.%p", self];
NSURLSessionConfiguration *configuration = nil;
- configuration = [NSURLSessionConfiguration pn_ephemeralSessionConfigurationWithIdentifier:identifier];
+ configuration = [NSURLSessionConfiguration pn_ephemeralSessionConfigurationWithIdentifier:self.identifier];
configuration.HTTPMaximumConnectionsPerHost = self.configuration.maximumConnections;
_HTTPAdditionalHeaders = [configuration.HTTPAdditionalHeaders copy];
_cachePolicy = configuration.requestCachePolicy;
@@ -394,7 +413,7 @@ - (NSURLSessionConfiguration *)urlSessionConfiguration {
- (void)URLSession:(NSURLSession *)session didBecomeInvalidWithError:(NSError *)error {
if (!error) return;
- [self.lock syncWriteAccessWithBlock:^{
+ [self.lock writeAccessWithBlock:^{
[self setupURLSession];
}];
}
diff --git a/PubNub/Network/Requests/Subscribe/PNSubscribeRequest.m b/PubNub/Network/Requests/Subscribe/PNSubscribeRequest.m
index b8fdc7ee0..bd9799d23 100644
--- a/PubNub/Network/Requests/Subscribe/PNSubscribeRequest.m
+++ b/PubNub/Network/Requests/Subscribe/PNSubscribeRequest.m
@@ -64,6 +64,7 @@ @implementation PNSubscribeRequest
- (PNTransportRequest *)request {
PNTransportRequest *request = super.request;
+ request.timeout = self.subscribeMaximumIdleTime;
request.cancellable = YES;
request.retriable = NO;
diff --git a/PubNub/Network/Responses/Subscribe/PNSubscribeCursorData.m b/PubNub/Network/Responses/Subscribe/PNSubscribeCursorData.m
index 6a6024068..8d0ca5535 100644
--- a/PubNub/Network/Responses/Subscribe/PNSubscribeCursorData.m
+++ b/PubNub/Network/Responses/Subscribe/PNSubscribeCursorData.m
@@ -32,6 +32,10 @@ @implementation PNSubscribeCursorData
};
}
++ (NSArray *)optionalKeys {
+ return @[@"region"];
+}
+
#pragma mark -
diff --git a/PubNub/Network/Responses/Subscribe/PNSubscribeEventData.m b/PubNub/Network/Responses/Subscribe/PNSubscribeEventData.m
index 88aed2be1..989e228b6 100644
--- a/PubNub/Network/Responses/Subscribe/PNSubscribeEventData.m
+++ b/PubNub/Network/Responses/Subscribe/PNSubscribeEventData.m
@@ -65,7 +65,7 @@ @implementation PNSubscribeEventData
}
+ (NSArray *)ignoredKeys {
- return @[@"timetoken"];
+ return @[@"timetoken", @"region"];
}
- (NSString *)subscription {
diff --git a/README.md b/README.md
index 59a595e8a..4e3ea444d 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# PubNub 5.6.0 for iOS 9+
+# PubNub 5.6.1 for iOS 9+
[![Twitter](https://img.shields.io/badge/twitter-%40PubNub-blue.svg?style=flat)](https://twitter.com/PubNub)
[![Twitter Releases](https://img.shields.io/badge/twitter-%40PubNubRelease-blue.svg?style=flat)](https://twitter.com/PubNubRelease)
[![CocoaPods Compatible](https://img.shields.io/cocoapods/v/PubNub.svg?style=flat)](https://img.shields.io/cocoapods/v/PubNub.svg)
diff --git a/Tests/Podfile.lock b/Tests/Podfile.lock
index ef40d5456..80d2100c2 100644
--- a/Tests/Podfile.lock
+++ b/Tests/Podfile.lock
@@ -1,9 +1,9 @@
PODS:
- Cucumberish (1.4.0)
- OCMock (3.6)
- - PubNub (5.5.0):
- - PubNub/Core (= 5.5.0)
- - PubNub/Core (5.5.0)
+ - PubNub (5.6.0):
+ - PubNub/Core (= 5.6.0)
+ - PubNub/Core (5.6.0)
- YAHTTPVCR (1.5.0)
DEPENDENCIES:
@@ -32,7 +32,7 @@ CHECKOUT OPTIONS:
SPEC CHECKSUMS:
Cucumberish: 6cbd0c1f50306b369acebfe7d9f514c9c287d26c
OCMock: 5ea90566be239f179ba766fd9fbae5885040b992
- PubNub: 17b22578c960a206863289c3662d0ccc803c71f7
+ PubNub: 4c06870a45eba7d59ac5f6598de28207fe7dac17
YAHTTPVCR: cb7a710d4289ee9b038fd708d2fb8df4e6521bc0
PODFILE CHECKSUM: fb38a10e9ab7ec6c9e4fe43e6a3b6ffc35154550
diff --git a/Tests/PubNub Tests.xcodeproj/project.pbxproj b/Tests/PubNub Tests.xcodeproj/project.pbxproj
index c29f369e5..394eb4338 100644
--- a/Tests/PubNub Tests.xcodeproj/project.pbxproj
+++ b/Tests/PubNub Tests.xcodeproj/project.pbxproj
@@ -54,6 +54,9 @@
A529271923B185F900FF46DD /* tests-configuration.json in Resources */ = {isa = PBXBuildFile; fileRef = A529271823B1855A00FF46DD /* tests-configuration.json */; };
A529271A23B185F900FF46DD /* tests-configuration.json in Resources */ = {isa = PBXBuildFile; fileRef = A529271823B1855A00FF46DD /* tests-configuration.json */; };
A529271D23B185FF00FF46DD /* tests-configuration.json in Resources */ = {isa = PBXBuildFile; fileRef = A529271823B1855A00FF46DD /* tests-configuration.json */; };
+ A53249102C304F90003510FF /* PNSubscribeTest.m in Sources */ = {isa = PBXBuildFile; fileRef = A532490F2C304F90003510FF /* PNSubscribeTest.m */; };
+ A53249112C304F90003510FF /* PNSubscribeTest.m in Sources */ = {isa = PBXBuildFile; fileRef = A532490F2C304F90003510FF /* PNSubscribeTest.m */; };
+ A53249122C304F90003510FF /* PNSubscribeTest.m in Sources */ = {isa = PBXBuildFile; fileRef = A532490F2C304F90003510FF /* PNSubscribeTest.m */; };
A53D0AEE23E9BF60001E72AF /* PNMembershipsObjectsAPICallBuilderTest.m in Sources */ = {isa = PBXBuildFile; fileRef = A53D0AED23E9BF60001E72AF /* PNMembershipsObjectsAPICallBuilderTest.m */; };
A53D0AEF23E9BF60001E72AF /* PNMembershipsObjectsAPICallBuilderTest.m in Sources */ = {isa = PBXBuildFile; fileRef = A53D0AED23E9BF60001E72AF /* PNMembershipsObjectsAPICallBuilderTest.m */; };
A53D0AF023E9BF60001E72AF /* PNMembershipsObjectsAPICallBuilderTest.m in Sources */ = {isa = PBXBuildFile; fileRef = A53D0AED23E9BF60001E72AF /* PNMembershipsObjectsAPICallBuilderTest.m */; };
@@ -230,6 +233,7 @@
A529270E23B181FE00FF46DD /* PNRecordableTestCase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PNRecordableTestCase.h; sourceTree = ""; };
A529270F23B181FE00FF46DD /* PNRecordableTestCase.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PNRecordableTestCase.m; sourceTree = ""; };
A529271823B1855A00FF46DD /* tests-configuration.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "tests-configuration.json"; sourceTree = ""; };
+ A532490F2C304F90003510FF /* PNSubscribeTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PNSubscribeTest.m; sourceTree = ""; };
A53D0AED23E9BF60001E72AF /* PNMembershipsObjectsAPICallBuilderTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PNMembershipsObjectsAPICallBuilderTest.m; sourceTree = ""; };
A53D0AF123E9F42B001E72AF /* PNChannelMembersObjectsAPICallBuilderTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PNChannelMembersObjectsAPICallBuilderTest.m; sourceTree = ""; };
A53D0AF523E9F7D7001E72AF /* PNChannelMetadataAPICallBuilderTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PNChannelMetadataAPICallBuilderTest.m; sourceTree = ""; };
@@ -532,6 +536,14 @@
path = Helpers;
sourceTree = "";
};
+ A532490E2C304F50003510FF /* Subscribe */ = {
+ isa = PBXGroup;
+ children = (
+ A532490F2C304F90003510FF /* PNSubscribeTest.m */,
+ );
+ path = Subscribe;
+ sourceTree = "";
+ };
A53D0AEB23E9BF2C001E72AF /* Interfaces */ = {
isa = PBXGroup;
children = (
@@ -644,6 +656,7 @@
A59ECFDA23BB56E900E84300 /* Core */ = {
isa = PBXGroup;
children = (
+ A532490E2C304F50003510FF /* Subscribe */,
79CFA2D526DE25A400D206D4 /* Access Manager */,
A53D0AEB23E9BF2C001E72AF /* Interfaces */,
A53D0B0D23EA07BD001E72AF /* Objects */,
@@ -1165,6 +1178,7 @@
A53D0B2123EA0DB7001E72AF /* PNMessageActionsTest.m in Sources */,
A5F8E9DD2476D47C007F79AB /* PNObjectsAPICallBuilderTest.m in Sources */,
79CFA2D926DE25DC00D206D4 /* PNPAMTokenTest.m in Sources */,
+ A53249112C304F90003510FF /* PNSubscribeTest.m in Sources */,
A53D0B2723EA0EAD001E72AF /* PNMessageCountTest.m in Sources */,
A53D0B0623EA063A001E72AF /* PNSignalAPIBuilderTest.m in Sources */,
A53D0B1C23EA0C5C001E72AF /* PNUUIDMetadataObjectsTest.m in Sources */,
@@ -1219,6 +1233,7 @@
A53D0B2023EA0DB7001E72AF /* PNMessageActionsTest.m in Sources */,
A5F8E9DC2476D47A007F79AB /* PNObjectsAPICallBuilderTest.m in Sources */,
79CFA2D826DE25DA00D206D4 /* PNPAMTokenTest.m in Sources */,
+ A53249102C304F90003510FF /* PNSubscribeTest.m in Sources */,
A53D0B2623EA0EAD001E72AF /* PNMessageCountTest.m in Sources */,
A53D0B0523EA063A001E72AF /* PNSignalAPIBuilderTest.m in Sources */,
A53D0B1B23EA0C5C001E72AF /* PNUUIDMetadataObjectsTest.m in Sources */,
@@ -1248,6 +1263,7 @@
A53D0B2223EA0DB7001E72AF /* PNMessageActionsTest.m in Sources */,
A5F8E9DE2476D47D007F79AB /* PNObjectsAPICallBuilderTest.m in Sources */,
79CFA2DA26DE25DD00D206D4 /* PNPAMTokenTest.m in Sources */,
+ A53249122C304F90003510FF /* PNSubscribeTest.m in Sources */,
A53D0B2823EA0EAD001E72AF /* PNMessageCountTest.m in Sources */,
A53D0B0723EA063A001E72AF /* PNSignalAPIBuilderTest.m in Sources */,
A53D0B1D23EA0C5C001E72AF /* PNUUIDMetadataObjectsTest.m in Sources */,
diff --git a/Tests/PubNub Tests.xcodeproj/xcshareddata/xcschemes/[iOS] Mocked Integration Tests.xcscheme b/Tests/PubNub Tests.xcodeproj/xcshareddata/xcschemes/[iOS] Mocked Integration Tests.xcscheme
index baed17c19..6978a60e9 100644
--- a/Tests/PubNub Tests.xcodeproj/xcshareddata/xcschemes/[iOS] Mocked Integration Tests.xcscheme
+++ b/Tests/PubNub Tests.xcodeproj/xcshareddata/xcschemes/[iOS] Mocked Integration Tests.xcscheme
@@ -40,6 +40,9 @@
ReferencedContainer = "container:PubNub Tests.xcodeproj">
+
+
diff --git a/Tests/Support Files/Fixtures/PNSubscribeIntegrationTest.bundle/ItShouldSubscribeToSingleChannelAndReceiveMessageWithUserTimetokenWhenPublished.json b/Tests/Support Files/Fixtures/PNSubscribeIntegrationTest.bundle/ItShouldSubscribeToSingleChannelAndReceiveMessageWithUserTimetokenWhenPublished.json
new file mode 100644
index 000000000..c3509bdfd
--- /dev/null
+++ b/Tests/Support Files/Fixtures/PNSubscribeIntegrationTest.bundle/ItShouldSubscribeToSingleChannelAndReceiveMessageWithUserTimetokenWhenPublished.json
@@ -0,0 +1,244 @@
+[
+ {
+ "id" : "6D9CF0BE-C72E-451C-BD56-ADC3759E4917",
+ "data" : {
+ "method" : "get",
+ "cls" : "NSURLRequest",
+ "cellular" : true,
+ "cache" : 1,
+ "timeout" : 60,
+ "cookies" : true,
+ "headers" : {
+ "User-Agent" : "iPhone; CPU iPhone OS 12.4.0 Version",
+ "Accept" : "*\/*",
+ "Connection" : "keep-alive",
+ "Accept-Encoding" : "gzip,deflate"
+ },
+ "pipeline" : false,
+ "network" : 0,
+ "url" : "https:\/\/ps.pndsn.com\/v2\/subscribe\/demo\/test-channel1\/0?pnsdk=PubNub-ObjC-iOS\/4.x.x&uuid=Serhii&tt=0&heartbeat=20"
+ },
+ "type" : 0
+ },
+ {
+ "id" : "6D9CF0BE-C72E-451C-BD56-ADC3759E4917",
+ "data" : {
+ "status" : 200,
+ "cls" : "NSHTTPURLResponse",
+ "url" : "https:\/\/ps.pndsn.com\/v2\/subscribe\/demo\/test-channel1\/0?pnsdk=PubNub-ObjC-iOS\/4.x.x&uuid=Serhii&tt=0&heartbeat=20",
+ "headers" : {
+ "Access-Control-Allow-Methods" : "GET",
+ "Content-Type" : "text\/javascript; charset=\"UTF-8\"",
+ "Access-Control-Allow-Origin" : "*",
+ "Date" : "Tue, 04 Feb 2020 13:10:11 GMT",
+ "Content-Length" : "45",
+ "Cache-Control" : "no-cache",
+ "Connection" : "keep-alive"
+ }
+ },
+ "type" : 1
+ },
+ {
+ "id" : "6D9CF0BE-C72E-451C-BD56-ADC3759E4917",
+ "data" : {
+ "cls" : "NSData",
+ "base64" : "eyJ0Ijp7InQiOiIxNTgwODIxODExNDczMDU1OSIsInIiOjEyfSwibSI6W119"
+ },
+ "type" : 2
+ },
+ {
+ "id" : "6D9CF0BE-C72E-451C-BD56-ADC3759E4917",
+ "type" : 4
+ },
+ {
+ "id" : "56380FEF-3510-4D26-8D88-22A028B35217",
+ "data" : {
+ "method" : "get",
+ "cls" : "NSURLRequest",
+ "cellular" : true,
+ "cache" : 1,
+ "timeout" : 60,
+ "cookies" : true,
+ "headers" : {
+ "User-Agent" : "iPhone; CPU iPhone OS 12.4.0 Version",
+ "Accept" : "*\/*",
+ "Connection" : "keep-alive",
+ "Accept-Encoding" : "gzip,deflate"
+ },
+ "pipeline" : false,
+ "network" : 0,
+ "url" : "https:\/\/ps.pndsn.com\/v2\/subscribe\/demo\/test-channel1\/0?uuid=Serhii&pnsdk=PubNub-ObjC-iOS\/4.x.x&tt=15808218114730559&heartbeat=20&tr=12"
+ },
+ "type" : 0
+ },
+ {
+ "id" : "9060F768-F824-4970-93AC-4BF1FA1121D5",
+ "data" : {
+ "method" : "get",
+ "cls" : "NSURLRequest",
+ "cellular" : true,
+ "cache" : 1,
+ "timeout" : 60,
+ "cookies" : true,
+ "headers" : {
+ "User-Agent" : "iPhone; CPU iPhone OS 12.4.0 Version",
+ "Accept" : "*\/*",
+ "Connection" : "keep-alive",
+ "Accept-Encoding" : "gzip,deflate"
+ },
+ "pipeline" : false,
+ "network" : 0,
+ "url" : "https:\/\/ps.pndsn.com\/publish\/demo\/demo\/0\/test-channel1\/0\/%7B%22test-message%22:%5B%22message%22%5D%7D?uuid=Serhii&pnsdk=PubNub-ObjC-iOS\/4.x.x&seqn=1"
+ },
+ "type" : 0
+ },
+ {
+ "id" : "9060F768-F824-4970-93AC-4BF1FA1121D5",
+ "data" : {
+ "status" : 200,
+ "cls" : "NSHTTPURLResponse",
+ "url" : "https:\/\/ps.pndsn.com\/publish\/demo\/demo\/0\/test-channel1\/0\/%7B%22test-message%22:%5B%22message%22%5D%7D?pnsdk=PubNub-ObjC-iOS\/4.x.x&seqn=1&uuid=Serhii",
+ "headers" : {
+ "Access-Control-Allow-Methods" : "GET",
+ "Content-Type" : "text\/javascript; charset=\"UTF-8\"",
+ "Access-Control-Allow-Origin" : "*",
+ "Date" : "Tue, 04 Feb 2020 13:10:14 GMT",
+ "Content-Length" : "30",
+ "Cache-Control" : "no-cache",
+ "Connection" : "keep-alive"
+ }
+ },
+ "type" : 1
+ },
+ {
+ "id" : "9060F768-F824-4970-93AC-4BF1FA1121D5",
+ "data" : {
+ "cls" : "NSData",
+ "base64" : "WzEsIlNlbnQiLCIxNTgwODIxODE0ODc5NTIwMCJd"
+ },
+ "type" : 2
+ },
+ {
+ "id" : "9060F768-F824-4970-93AC-4BF1FA1121D5",
+ "type" : 4
+ },
+ {
+ "id" : "56380FEF-3510-4D26-8D88-22A028B35217",
+ "data" : {
+ "status" : 200,
+ "cls" : "NSHTTPURLResponse",
+ "url" : "https:\/\/ps.pndsn.com\/v2\/subscribe\/demo\/test-channel1\/0?uuid=Serhii&pnsdk=PubNub-ObjC-iOS\/4.x.x&tt=15808218114730559&heartbeat=20&tr=12",
+ "headers" : {
+ "Access-Control-Allow-Methods" : "GET",
+ "Content-Type" : "text\/javascript; charset=\"UTF-8\"",
+ "Access-Control-Allow-Origin" : "*",
+ "Date" : "Tue, 04 Feb 2020 13:10:14 GMT",
+ "Content-Length" : "291",
+ "Cache-Control" : "no-cache",
+ "Connection" : "keep-alive"
+ }
+ },
+ "type" : 1
+ },
+ {
+ "id" : "56380FEF-3510-4D26-8D88-22A028B35217",
+ "data" : {
+ "cls" : "NSData",
+ "base64" : "eyJ0Ijp7InQiOiIxNTgwODIxODE0ODgwNDc4NyIsInIiOjEyfSwibSI6W3siYSI6IjUiLCJmIjowLCJpIjoiU2VyaGlpIiwicyI6MTAsInAiOnsidCI6IjE1ODA4MjE4MTQ4Nzk1MjAwIiwiciI6MTJ9LCJvIjp7InQiOiIxNTgwODIxODE0ODc5NTE5OSJ9LCJrIjoiZGVtbyIsImMiOiJ0ZXN0LWNoYW5uZWwxIiwiZCI6eyJ0ZXN0LW1lc3NhZ2UiOlsibWVzc2FnZSJdfX1dfQ=="
+ },
+ "type" : 2
+ },
+ {
+ "id" : "56380FEF-3510-4D26-8D88-22A028B35217",
+ "type" : 4
+ },
+ {
+ "id" : "8166D76F-F897-4ABB-934A-13726D856948",
+ "data" : {
+ "method" : "get",
+ "cls" : "NSURLRequest",
+ "cellular" : true,
+ "cache" : 1,
+ "timeout" : 60,
+ "cookies" : true,
+ "headers" : {
+ "User-Agent" : "iPhone; CPU iPhone OS 12.4.0 Version",
+ "Accept" : "*\/*",
+ "Connection" : "keep-alive",
+ "Accept-Encoding" : "gzip,deflate"
+ },
+ "pipeline" : false,
+ "network" : 0,
+ "url" : "https:\/\/ps.pndsn.com\/v2\/subscribe\/demo\/test-channel1\/0?uuid=Serhii&pnsdk=PubNub-ObjC-iOS\/4.x.x&tt=15808218148804787&heartbeat=20&tr=12"
+ },
+ "type" : 0
+ },
+ {
+ "id" : "8166D76F-F897-4ABB-934A-13726D856948",
+ "data" : {
+ "code" : -999,
+ "info" : {
+ "NSErrorFailingURLStringKey" : "https:\/\/ps.pndsn.com\/v2\/subscribe\/demo\/test-channel1\/0?uuid=Serhii&pnsdk=PubNub-ObjC-iOS\/4.x.x&tt=15808218148804787&heartbeat=20&tr=12",
+ "NSLocalizedDescription" : "cancelled",
+ "NSErrorFailingURLKey" : "https:\/\/ps.pndsn.com\/v2\/subscribe\/demo\/test-channel1\/0?uuid=Serhii&pnsdk=PubNub-ObjC-iOS\/4.x.x&tt=15808218148804787&heartbeat=20&tr=12"
+ },
+ "cls" : "NSError",
+ "domain" : "NSURLErrorDomain"
+ },
+ "type" : 3
+ },
+ {
+ "id" : "1966F67F-1E40-41C0-B669-9A9607D9514C",
+ "data" : {
+ "method" : "get",
+ "cls" : "NSURLRequest",
+ "cellular" : true,
+ "cache" : 1,
+ "timeout" : 60,
+ "cookies" : true,
+ "headers" : {
+ "User-Agent" : "iPhone; CPU iPhone OS 12.4.0 Version",
+ "Accept" : "*\/*",
+ "Connection" : "keep-alive",
+ "Accept-Encoding" : "gzip,deflate"
+ },
+ "pipeline" : false,
+ "network" : 0,
+ "url" : "https:\/\/ps.pndsn.com\/v2\/presence\/sub_key\/demo\/channel\/test-channel1\/leave?uuid=Serhii&pnsdk=PubNub-ObjC-iOS\/4.x.x"
+ },
+ "type" : 0
+ },
+ {
+ "id" : "1966F67F-1E40-41C0-B669-9A9607D9514C",
+ "data" : {
+ "status" : 200,
+ "cls" : "NSHTTPURLResponse",
+ "url" : "https:\/\/ps.pndsn.com\/v2\/presence\/sub_key\/demo\/channel\/test-channel1\/leave?uuid=Serhii&pnsdk=PubNub-ObjC-iOS\/4.x.x",
+ "headers" : {
+ "Access-Control-Allow-Methods" : "OPTIONS, GET, POST",
+ "Content-Type" : "text\/javascript; charset=\"UTF-8\"",
+ "Server" : "Pubnub Presence",
+ "Access-Control-Allow-Origin" : "*",
+ "Age" : "0",
+ "Date" : "Tue, 04 Feb 2020 13:10:15 GMT",
+ "Accept-Ranges" : "bytes",
+ "Content-Length" : "74",
+ "Cache-Control" : "no-cache",
+ "Connection" : "keep-alive"
+ }
+ },
+ "type" : 1
+ },
+ {
+ "id" : "1966F67F-1E40-41C0-B669-9A9607D9514C",
+ "data" : {
+ "cls" : "NSData",
+ "base64" : "eyJzdGF0dXMiOiAyMDAsICJtZXNzYWdlIjogIk9LIiwgImFjdGlvbiI6ICJsZWF2ZSIsICJzZXJ2aWNlIjogIlByZXNlbmNlIn0="
+ },
+ "type" : 2
+ },
+ {
+ "id" : "1966F67F-1E40-41C0-B669-9A9607D9514C",
+ "type" : 4
+ }
+]
diff --git a/Tests/Tests/Integration/PNSubscribeIntegrationTest.m b/Tests/Tests/Integration/PNSubscribeIntegrationTest.m
index 2c0d8f39a..a32b452b8 100644
--- a/Tests/Tests/Integration/PNSubscribeIntegrationTest.m
+++ b/Tests/Tests/Integration/PNSubscribeIntegrationTest.m
@@ -3,6 +3,7 @@
* @copyright © 2010-2020 PubNub, Inc.
*/
#import "PNRecordableTestCase.h"
+#import "PNSubscribeEventData+Private.h"
#import "NSString+PNTest.h"
@@ -1387,6 +1388,39 @@ - (void)testItShouldSubscribeToSingleChannelAndReceiveMessageWhenPublished {
}];
}
+- (void)testItShouldSubscribeToSingleChannelAndReceiveMessageWithUserTimetokenWhenPublished {
+ NSDictionary *publishedMessage = @{ @"test-message": [self randomizedValuesWithValues:@[@"message"]] };
+ NSString *channel = [self channelWithName:@"test-channel1"];
+
+
+ [self subscribeClient:self.client toChannels:@[channel] withPresence:NO];
+ [self waitTask:@"waitForDistribution" completionFor:(YHVVCR.cassette.isNewCassette ? 3.f : 0.f)];
+
+
+ [self waitToCompleteIn:self.testCompletionDelay codeBlock:^(dispatch_block_t handler) {
+ [self addMessageHandlerForClient:self.client
+ withBlock:^(PubNub *client, PNMessageResult *message, BOOL *remove) {
+
+ if ([message.data.publisher isEqualToString:self.client.currentConfiguration.userID]) {
+ XCTAssertEqualObjects(message.data.message, publishedMessage);
+ XCTAssertEqualObjects(message.data.subscription, channel);
+ XCTAssertEqualObjects(message.data.channel, channel);
+ XCTAssertEqualObjects(message.data.userTimetoken.timetoken,
+ @(message.data.timetoken.unsignedIntegerValue - 1));
+ XCTAssertNil(message.data.userTimetoken.region);
+ XCTAssertNotNil(message.data.userTimetoken);
+ *remove = YES;
+
+ handler();
+ }
+ }];
+
+ [self.client publish:publishedMessage toChannel:channel withCompletion:^(PNPublishStatus *status) {
+ XCTAssertFalse(status.isError);
+ }];
+ }];
+}
+
/**
* @brief Follow instructions to simulate server response with "broken" payload.
*
diff --git a/Tests/Tests/Unit/Core/Subscribe/PNSubscribeTest.m b/Tests/Tests/Unit/Core/Subscribe/PNSubscribeTest.m
new file mode 100644
index 000000000..f6b9aae2b
--- /dev/null
+++ b/Tests/Tests/Unit/Core/Subscribe/PNSubscribeTest.m
@@ -0,0 +1,57 @@
+#import "PNRecordableTestCase.h"
+#import
+#import
+#import "PNBaseRequest+Private.h"
+
+
+NS_ASSUME_NONNULL_BEGIN
+
+#pragma mark Interface declaration
+
+@interface PNSubscribeTest : PNRecordableTestCase
+
+
+#pragma mark -
+
+
+@end
+
+NS_ASSUME_NONNULL_END
+
+
+#pragma mark - Tests
+
+@implementation PNSubscribeTest
+
+
+#pragma mark - VCR configuration
+
+- (BOOL)shouldSetupVCR {
+ return NO;
+}
+
+#pragma mark - Tests :: Request
+
+- (void)testItShouldSetProperRequestValues {
+ PNSubscribeRequest *request = [PNSubscribeRequest requestWithChannels:@[@"ch-a"] channelGroups:@[@"gr-a"]];
+
+ id clientTransportMock = [self mockForObject:self.client.subscriptionNetwork];
+ id recorded = OCMExpect([clientTransportMock sendRequest:[OCMArg isKindOfClass:[PNTransportRequest class]]
+ withCompletionBlock:[OCMArg any]])
+ .andDo(^(NSInvocation *invocation) {
+ PNTransportRequest *transportRequest = [self objectForInvocation:invocation argumentAtIndex:1];
+ NSLog(@"CALLED");
+
+ XCTAssertEqual(transportRequest.timeout, self.client.configuration.subscribeMaximumIdleTime);
+ XCTAssertTrue(transportRequest.cancellable);
+ XCTAssertFalse(transportRequest.retriable);
+ });
+
+ [self waitForObject:clientTransportMock recordedInvocationCall:recorded afterBlock:^{
+ [self.client subscribeWithRequest:request];
+ }];
+}
+
+#pragma mark -
+
+@end
diff --git a/VERSION b/VERSION
index 1bc788d3b..b7c75422b 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-5.6.0
+5.6.1