diff --git a/.gitignore b/.gitignore index 541965de2..827bedd6f 100644 --- a/.gitignore +++ b/.gitignore @@ -55,3 +55,13 @@ Icon? ehthumbs.db Thumbs.db .idea/ + +# Removed because it has some weird file names that Windows can't handle # +########################################################################## +iOS/tests/* + +# Android # +########### +**/*.approj/configuration.json +**/*.approj/Headers +**/*.approj/targets diff --git a/PubNub/Core/PubNub+Core.m b/PubNub/Core/PubNub+Core.m index f9db95101..eacd53682 100644 --- a/PubNub/Core/PubNub+Core.m +++ b/PubNub/Core/PubNub+Core.m @@ -16,6 +16,9 @@ #import "PNNetwork.h" #import "PNHelpers.h" +#ifdef PGDROID +#import +#endif #pragma mark Static @@ -70,6 +73,8 @@ @interface PubNub () */ @property (nonatomic, strong) PNNetwork *serviceNetwork; +@property (nonatomic, strong) PNNetwork *historyNetwork; + /** @brief Stores reference on reachability helper. @discussion Helper used by client to know about when something happened with network and when it is @@ -206,7 +211,7 @@ - (instancetype)initWithConfiguration:(PNConfiguration *)configuration _heartbeatManager = [PNHeartbeat heartbeatForClient:self]; [self addListener:self]; [self prepareReachability]; -#if __IPHONE_OS_VERSION_MIN_REQUIRED +#if __IPHONE_OS_VERSION_MIN_REQUIRED || defined(PGDROID) NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; [notificationCenter addObserver:self selector:@selector(handleContextTransition:) name:UIApplicationWillEnterForegroundNotification object:nil]; @@ -293,7 +298,6 @@ - (void)setRecentClientStatus:(PNStatusCategory)recentClientStatus { // Check whether previous client state reported unexpected disconnection from remote data // objects live feed or not. - PNStatusCategory previousState = self.recentClientStatus; PNStatusCategory currentState = recentClientStatus; // In case if client disconnected only from one of it's channels it should keep 'connected' @@ -308,25 +312,23 @@ - (void)setRecentClientStatus:(PNStatusCategory)recentClientStatus { // Check whether client reported unexpected disconnection. if (currentState == PNUnexpectedDisconnectCategory) { - // Check whether client unexpectedly disconnected while tried to subscribe or not. - if (previousState != PNDisconnectedCategory) { - - // Dispatching check block with small delay, which will allow to fire reachability - // change event. - __weak __typeof(self) weakSelf = self; - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), - dispatch_get_main_queue(), ^{ - - // Silence static analyzer warnings. - // Code is aware about this case and at the end will simply call on 'nil' object - // method. In most cases if referenced object become 'nil' it mean what there is no - // more need in it and probably whole client instance has been deallocated. - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wreceiver-is-weak" - [weakSelf.reachability startServicePing]; - #pragma clang diagnostic pop - }); - } + // Dispatching check block with small delay, which will allow to fire reachability + // change event. + __weak __typeof(self) weakSelf = self; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), + dispatch_get_main_queue(), ^{ + + // Silence static analyzer warnings. + // Code is aware about this case and at the end will simply call on 'nil' object + // method. In most cases if referenced object become 'nil' it mean what there is no + // more need in it and probably whole client instance has been deallocated. + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wreceiver-is-weak" + [weakSelf.reachability startServicePing]; + #pragma clang diagnostic pop + }); + } else { + [self.reachability stopServicePing]; } } @@ -348,7 +350,6 @@ - (void)prepareReachability { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wreceiver-is-weak" #pragma clang diagnostic ignored "-Warc-repeated-use-of-weak" - [weakSelf.reachability stopServicePing]; [weakSelf.subscriberManager restoreSubscriptionCycleIfRequiredWithCompletion:nil]; #pragma clang diagnostic pop } @@ -362,10 +363,14 @@ - (void)prepareNetworkManagers { _subscriptionNetwork = [PNNetwork networkForClient:self requestTimeout:_configuration.subscribeMaximumIdleTime - maximumConnections:1 longPoll:YES]; + maximumConnections:2 longPoll:YES]; _serviceNetwork = [PNNetwork networkForClient:self requestTimeout:_configuration.nonSubscribeRequestTimeout maximumConnections:3 longPoll:NO]; + _historyNetwork = [PNNetwork networkForClient:self + requestTimeout:_configuration.historyRequestTimeout + maximumConnections:1 + longPoll:NO]; } @@ -387,6 +392,12 @@ - (void)processOperation:(PNOperationType)operationType [self.subscriptionNetwork processOperation:operationType withParameters:parameters data:data completionBlock:block]; } + else if (operationType == PNHistoryOperation) { + [self.historyNetwork processOperation:operationType + withParameters:parameters + data:data + completionBlock:block]; + } else { [self.serviceNetwork processOperation:operationType withParameters:parameters @@ -464,7 +475,7 @@ - (void)callBlock:(id)block status:(BOOL)callingStatusBlock withResult:(PNResult - (void)client:(PubNub *)__unused client didReceiveStatus:(PNSubscribeStatus *)status { if (status.category == PNConnectedCategory || status.category == PNDisconnectedCategory || - status.category == PNUnexpectedDisconnectCategory) { + status.category == PNUnexpectedDisconnectCategory || status.category == PNReconnectedCategory) { self.recentClientStatus = status.category; } @@ -475,7 +486,7 @@ - (void)client:(PubNub *)__unused client didReceiveStatus:(PNSubscribeStatus *)s - (void)handleContextTransition:(NSNotification *)notification { -#if __IPHONE_OS_VERSION_MIN_REQUIRED +#if __IPHONE_OS_VERSION_MIN_REQUIRED || defined(PGDROID) if ([notification.name isEqualToString:UIApplicationDidEnterBackgroundNotification]) { DDLogClientInfo([[self class] ddLogLevel], @" Did enter background execution context."); @@ -503,7 +514,7 @@ - (void)handleContextTransition:(NSNotification *)notification { - (void)dealloc { -#if __IPHONE_OS_VERSION_MIN_REQUIRED +#if __IPHONE_OS_VERSION_MIN_REQUIRED || defined(PGDROID) NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; [notificationCenter removeObserver:self name:UIApplicationWillEnterForegroundNotification object:nil]; diff --git a/PubNub/Core/PubNub+Publish.m b/PubNub/Core/PubNub+Publish.m index 5cf5f5712..3c7130861 100644 --- a/PubNub/Core/PubNub+Publish.m +++ b/PubNub/Core/PubNub+Publish.m @@ -179,8 +179,7 @@ - (void) publish:(id)message toChannel:(NSString *)channel DDLogAPICall([[self class] ddLogLevel], @" Publish%@ message to '%@' channel%@%@", (compressed ? @" compressed" : @""), (channel?: @""), (!shouldStore ? @" which won't be saved in hisotry" : @""), - (!compressed ? [NSString stringWithFormat:@": %@", - (messageForPublish?: @"")] : @".")); + ([NSString stringWithFormat:@": %@", (messageForPublish?: @"")])); [self processOperation:PNPublishOperation withParameters:parameters data:publishData completionBlock:^(PNStatus *status) { diff --git a/PubNub/Data/Managers/PNSubscriber.m b/PubNub/Data/Managers/PNSubscriber.m index 7e89454c1..dbdff1ede 100644 --- a/PubNub/Data/Managers/PNSubscriber.m +++ b/PubNub/Data/Managers/PNSubscriber.m @@ -566,7 +566,7 @@ - (void)updateStateTo:(PNSubscriberState)state withStatus:(PNSubscribeStatus *)s currentState == PNConnectedSubscriberState); category = ((targetState == PNDisconnectedSubscriberState) ? PNDisconnectedCategory : PNUnexpectedDisconnectCategory); - self.mayRequireSubscriptionRestore = shouldHandleTransition; + self.mayRequireSubscriptionRestore = YES; } // Check whether transit to 'access denied' state. else if (targetState == PNAccessRightsErrorSubscriberState) { @@ -718,25 +718,31 @@ - (void)restoreSubscriptionCycleIfRequiredWithCompletion:(PNSubscriberCompletion __block BOOL shouldRestore; __block BOOL ableToRestore; + DDLogAPICall([[self class] ddLogLevel], @"Called restore subscription cycle with block: %@", block); + + __weak __typeof(self) weakSelf = self; dispatch_sync(self.resourceAccessQueue, ^{ - + __strong __typeof(self) self = weakSelf; + DDLogAPICall([[self class] ddLogLevel], @"Checking if should and able to restore subscription cycle with block: %@", block); shouldRestore = (self.currentState == PNDisconnectedUnexpectedlySubscriberState && self.mayRequireSubscriptionRestore); ableToRestore = ([self.channelsSet count] || [self.channelGroupsSet count] || [self.presenceChannelsSet count]); }); if (shouldRestore && ableToRestore) { - + DDLogAPICall([[self class] ddLogLevel], @"Restoring subscription cycle with block: %@", block); [self subscribe:YES withState:nil completion:block]; - } - else if (block) { - - block(nil); + } else { + DDLogAPICall([[self class] ddLogLevel], @"Not restoring subscription cycle with block (%d, %d): %@", shouldRestore, ableToRestore, block); + if (block) { + block(nil); + } } } - (void)continueSubscriptionCycleIfRequiredWithCompletion:(PNSubscriberCompletionBlock)block { + DDLogAPICall([[self class] ddLogLevel], @"Continuing subscription cycle with block: %@", block); [self subscribe:NO withState:nil completion:block]; } @@ -853,6 +859,12 @@ - (void)handleSubscriptionStatus:(PNSubscribeStatus *)status { if (!status.isError && status.category != PNCancelledCategory) { [self handleSuccessSubscriptionStatus:status]; +#ifdef PGDROID + // 2016/02/16 : this PG addition is causing crashes on Android ... Sending an instance of PNErrorStatus to -handleSuccessSubscriptionStatus: is not valid since it references properties specific to PNSubscribeStatus ... unsure why we're not seeing this in crash groups on iOS ... LONG TERM solution is to probably revert both of the commits around this and roll forward to the latest PubNub and run full QA ;-) +#else + } else if (status.isError && status.category == PNTimeoutCategory) { + [self handleSuccessSubscriptionStatus:status]; +#endif } else { @@ -1051,6 +1063,7 @@ - (void)handleLiveFeedEvents:(PNSubscribeStatus *)status { // it and probably whole client instance has been deallocated. #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wreceiver-is-weak" + PNSubscribeStatus *copiedStatus = [status copy]; [self.client.listenersManager notifyWithBlock:^{ // Iterate through array with notifications and report back using callback blocks to the @@ -1078,7 +1091,7 @@ - (void)handleLiveFeedEvents:(PNSubscribeStatus *)status { } } - id eventResultObject = [status copyWithMutatedData:event]; + id eventResultObject = [copiedStatus copyWithMutatedData:event]; if (isPresenceEvent) { object_setClass(eventResultObject, [PNPresenceEventResult class]); diff --git a/PubNub/Data/PNAES.m b/PubNub/Data/PNAES.m index 4042ceb99..ae37a725d 100644 --- a/PubNub/Data/PNAES.m +++ b/PubNub/Data/PNAES.m @@ -356,8 +356,12 @@ + (NSError *)errorFor:(CCCryptorStatus)status { errorCode = kPNAESInsufficientMemoryError; break; case kCCDecodeError: +#ifdef PGDROID +# warning HC SVNT DRACONES! : CommonCrypto is not fully implemented on PGDroid ... +#else case kCCOverflow: case kCCRNGFailure: +#endif description = @"Provided data can't be processed (data can be not encryped)."; errorCode = kPNAESDecryptionError; diff --git a/PubNub/Data/PNConfiguration.h b/PubNub/Data/PNConfiguration.h index 3b0d5b05f..8f2f8bf21 100644 --- a/PubNub/Data/PNConfiguration.h +++ b/PubNub/Data/PNConfiguration.h @@ -111,6 +111,8 @@ */ @property (nonatomic, assign) NSTimeInterval nonSubscribeRequestTimeout; +@property (nonatomic, assign) NSTimeInterval historyRequestTimeout; + /** @brief Reference on number of seconds which is used by server to track whether client still subscribed on remote data objects live feed or not. @@ -187,6 +189,8 @@ */ @property (nonatomic, assign, getter = shouldTryCatchUpOnSubscriptionRestore) BOOL catchUpOnSubscriptionRestore; +@property (nonatomic, assign) long port; + /** @brief Construct configuration instance using minimal required data. diff --git a/PubNub/Data/PNConfiguration.m b/PubNub/Data/PNConfiguration.m index 4caf09887..a9a6ac490 100644 --- a/PubNub/Data/PNConfiguration.m +++ b/PubNub/Data/PNConfiguration.m @@ -3,7 +3,7 @@ @since 4.0 @copyright © 2009-2015 PubNub, Inc. */ -#if __IPHONE_OS_VERSION_MIN_REQUIRED +#if __IPHONE_OS_VERSION_MIN_REQUIRED || defined(PGDROID) #import #elif __MAC_OS_X_VERSION_MIN_REQUIRED #import @@ -112,10 +112,12 @@ - (instancetype)initWithPublishKey:(NSString *)publishKey subscribeKey:(NSString _uuid = [[[NSUUID UUID] UUIDString] copy]; _subscribeMaximumIdleTime = kPNDefaultSubscribeMaximumIdleTime; _nonSubscribeRequestTimeout = kPNDefaultNonSubscribeRequestTimeout; + _historyRequestTimeout = kPNDefaultNonSubscribeRequestTimeout; _TLSEnabled = kPNDefaultIsTLSEnabled; _keepTimeTokenOnListChange = kPNDefaultShouldKeepTimeTokenOnListChange; _restoreSubscription = kPNDefaultShouldRestoreSubscription; _catchUpOnSubscriptionRestore = kPNDefaultShouldTryCatchUpOnSubscriptionRestore; + _port = _TLSEnabled ? 443 : 80; } return self; @@ -133,12 +135,14 @@ - (id)copyWithZone:(NSZone *)zone { configuration.cipherKey = self.cipherKey; configuration.subscribeMaximumIdleTime = self.subscribeMaximumIdleTime; configuration.nonSubscribeRequestTimeout = self.nonSubscribeRequestTimeout; + configuration.historyRequestTimeout = self.historyRequestTimeout; configuration.presenceHeartbeatValue = self.presenceHeartbeatValue; configuration.presenceHeartbeatInterval = self.presenceHeartbeatInterval; configuration.TLSEnabled = self.isTLSEnabled; configuration.keepTimeTokenOnListChange = self.shouldKeepTimeTokenOnListChange; configuration.restoreSubscription = self.shouldRestoreSubscription; configuration.catchUpOnSubscriptionRestore = self.shouldTryCatchUpOnSubscriptionRestore; + configuration.port = self.port; return configuration; } @@ -147,7 +151,7 @@ - (id)copyWithZone:(NSZone *)zone { #pragma mark - Misc - (NSString *)uniqueDeviceIdentifier { -#if __IPHONE_OS_VERSION_MIN_REQUIRED +#if __IPHONE_OS_VERSION_MIN_REQUIRED || defined(PGDROID) return [[[UIDevice currentDevice] identifierForVendor] UUIDString]; #elif __MAC_OS_X_VERSION_MIN_REQUIRED return ([self serialNumber]?: [self macAddress]); diff --git a/PubNub/Data/Service Objects/PNErrorStatus.m b/PubNub/Data/Service Objects/PNErrorStatus.m index b205d9659..9b33cf711 100644 --- a/PubNub/Data/Service Objects/PNErrorStatus.m +++ b/PubNub/Data/Service Objects/PNErrorStatus.m @@ -23,8 +23,14 @@ - (NSArray *)channelGroups { } - (NSString *)information { - - return self.serviceData[@"information"]; + + if ([self.serviceData isKindOfClass:[NSDictionary class]]) { + return self.serviceData[@"information"]; + } else if ([self.serviceData isKindOfClass:[NSString class]]) { + return (NSString *)self.serviceData; + } else { + return [self.serviceData description]; + } } - (id)data { diff --git a/PubNub/Data/Service Objects/PNResult.m b/PubNub/Data/Service Objects/PNResult.m index 586f55721..8daf49cf6 100644 --- a/PubNub/Data/Service Objects/PNResult.m +++ b/PubNub/Data/Service Objects/PNResult.m @@ -67,15 +67,28 @@ - (instancetype)initForOperation:(PNOperationType)operation processedData = [dataForUpdate copy]; _statusCode = (([statusCode integerValue] > 200) ? [statusCode integerValue] : _statusCode); } - _serviceData = [processedData copy]; + _serviceData = [PNResult normalizeServiceData:processedData]; } return self; } - (id)copyWithZone:(NSZone *)zone { - PNResult *result = [[[self class] allocWithZone:zone] init]; + [self fillCopy:result shouldCopyServiceData:YES]; + return result; +} + +- (instancetype)copyWithMutatedData:(id)data { + + PNResult *result = [[[self class] alloc] init]; + [self fillCopy:result shouldCopyServiceData:NO]; + [result updateData:data]; + + return result; +} + +- (void)fillCopy:(PNResult *)result shouldCopyServiceData:(BOOL)shouldCopyServiceData { result.statusCode = self.statusCode; result.operation = self.operation; result.TLSEnabled = self.isTLSEnabled; @@ -83,22 +96,28 @@ - (id)copyWithZone:(NSZone *)zone { result.authKey = self.authKey; result.origin = self.origin; result.clientRequest = self.clientRequest; - result.serviceData = self.serviceData; - - return result; + + if (shouldCopyServiceData) { + [result updateData:self.serviceData]; + } } -- (instancetype)copyWithMutatedData:(id)data { - - PNResult *result = [self copy]; - result->_serviceData = [data copy]; - - return result; ++ (NSDictionary *)normalizeServiceData:(id)serviceData { + if (serviceData && ![serviceData isKindOfClass:[NSDictionary class]]) { + id copyableServiceData; + if ([serviceData respondsToSelector:@selector(copy)]) { + copyableServiceData = serviceData; + } else { + copyableServiceData = [serviceData description]; + } + return @{@"information": [copyableServiceData copy]}; + } + return [serviceData copy]; } - (void)updateData:(id)data { - _serviceData = [data copy]; + _serviceData = [PNResult normalizeServiceData:data]; } diff --git a/PubNub/Misc/Logger/PNLog.h b/PubNub/Misc/Logger/PNLog.h index c1feab169..ada3a5094 100644 --- a/PubNub/Misc/Logger/PNLog.h +++ b/PubNub/Misc/Logger/PNLog.h @@ -121,6 +121,9 @@ */ + (BOOL)isDumpingToFile; ++ (void)rollLogFileWithCompletion:(void (^)(void))completionBlock; ++ (NSString *)currentLogFilePath; + #pragma mark - diff --git a/PubNub/Misc/Logger/PNLog.m b/PubNub/Misc/Logger/PNLog.m index 790a80bc4..99a35c423 100644 --- a/PubNub/Misc/Logger/PNLog.m +++ b/PubNub/Misc/Logger/PNLog.m @@ -140,8 +140,8 @@ - (void)prepare { // Adding file logger for messages sent by PubNub client. self.fileLogger = [[DDFileLogger alloc] initWithLogFileManager:[PNLogFileManager new]]; self.fileLogger.maximumFileSize = (5 * 1024 * 1024); - self.fileLogger.logFileManager.maximumNumberOfLogFiles = 5; - self.fileLogger.logFileManager.logFilesDiskQuota = (50 * 1024 * 1024); + self.fileLogger.logFileManager.maximumNumberOfLogFiles = 0; + self.fileLogger.logFileManager.logFilesDiskQuota = 0; } + (void)enabled:(BOOL)isLoggingEnabled { @@ -227,6 +227,30 @@ + (BOOL)isDumpingToFile { return [self sharedInstance].isFileLoggerActive; } +- (void)rollLogFileWithCompletion:(void (^)(void))completionBlock { + if (self.isFileLoggerActive) { + [self.fileLogger rollLogFileWithCompletionBlock:completionBlock]; + } +} + ++ (void)rollLogFileWithCompletion:(void (^)(void))completionBlock { + [[self sharedInstance] rollLogFileWithCompletion:completionBlock]; +} + +- (NSString *)currentLogFilePath { + if (self.isFileLoggerActive) { + DDLogFileInfo *fileInfo = [self.fileLogger currentLogFileInfo]; + if (fileInfo) { + return fileInfo.filePath; + } + } + return nil; +} + ++ (NSString *)currentLogFilePath { + return [[self sharedInstance] currentLogFilePath]; +} + #pragma mark - diff --git a/PubNub/Misc/Logger/PNLogFileManager.m b/PubNub/Misc/Logger/PNLogFileManager.m index 59d197b1a..e6d417d73 100644 --- a/PubNub/Misc/Logger/PNLogFileManager.m +++ b/PubNub/Misc/Logger/PNLogFileManager.m @@ -5,31 +5,38 @@ */ #import "PNLogFileManager.h" +@interface PNLogFileManager() + +@property (nonatomic, readwrite, strong) NSDateFormatter *dateFormatter; + +@end #pragma mark Interface implementation @implementation PNLogFileManager - (instancetype)init { - // Configure file manager with default storage in application's Documents folder. NSArray *documents = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); - return [self initWithLogsDirectory:[documents lastObject]]; + if (self = [self initWithLogsDirectory:[documents lastObject]]) { + NSString *dateFormat = @"yyyy'-'MM'-'dd'T'HH'-'mm'-'ss'"; + _dateFormatter = [[NSDateFormatter alloc] init]; + [_dateFormatter setLocale:[NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"]]; + [_dateFormatter setDateFormat:dateFormat]; + [_dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]]; + } + return self; } - (NSString *)newLogFileName { - - return [[super newLogFileName] stringByReplacingOccurrencesOfString:@".log" - withString:@".txt"]; + NSString *formattedDate = [self.dateFormatter stringFromDate:[NSDate date]]; + return [[NSString alloc] initWithFormat:@"pubnub-console-dump-%@.log", formattedDate]; } - (BOOL)isLogFile:(NSString *)fileName { - - NSString *originalName = [fileName stringByReplacingOccurrencesOfString:@".txt" - withString:@".log"]; - - return [super isLogFile:originalName]; + return [fileName hasPrefix:@"pubnub-console-dump-"] + && [fileName hasSuffix:@".log"]; } #pragma mark - diff --git a/PubNub/Misc/PNConstants.h b/PubNub/Misc/PNConstants.h index c511e78b2..a3b964070 100644 --- a/PubNub/Misc/PNConstants.h +++ b/PubNub/Misc/PNConstants.h @@ -20,7 +20,7 @@ static NSString * const kPNLibraryVersion = @"4.0.3"; static NSString * const kPNBranchName = @"master"; static NSString * const kPNCommit = @"a9c8c4648958b86cac4b59f7092cc6ed06dd7626"; -#if __IPHONE_OS_VERSION_MIN_REQUIRED +#if __IPHONE_OS_VERSION_MIN_REQUIRED || defined(PGDROID) static NSString * const kPNClientName = @"ObjC-iOS"; #elif __MAC_OS_X_VERSION_MIN_REQUIRED static NSString * const kPNClientName = @"ObjC-MacOS"; diff --git a/PubNub/Network/PNNetwork.m b/PubNub/Network/PNNetwork.m index 83a8c14cb..2e426e0e0 100644 --- a/PubNub/Network/PNNetwork.m +++ b/PubNub/Network/PNNetwork.m @@ -18,6 +18,9 @@ #import "PNConstants.h" #import "PNHelpers.h" +#ifdef PGDROID + #import +#endif #pragma mark CocoaLumberjack logging support @@ -813,6 +816,7 @@ - (NSURLSessionConfiguration *)configurationWithRequestTimeout:(NSTimeInterval)t // Prepare base configuration with predefined timeout values and maximum connections // to same host (basically how many requests can be handled at once). NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration ephemeralSessionConfiguration]; + configuration.URLCache = nil; configuration.requestCachePolicy = NSURLRequestReloadIgnoringLocalCacheData; configuration.HTTPShouldUsePipelining = !self.forLongPollRequests; configuration.HTTPAdditionalHeaders = _additionalHeaders; @@ -841,14 +845,14 @@ - (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configur - (NSURL *)requestBaseURL { - return [NSURL URLWithString:[NSString stringWithFormat:@"http%@://%@", - (_configuration.TLSEnabled ? @"s" : @""), _configuration.origin]]; + return [NSURL URLWithString:[[NSString alloc] initWithFormat:@"http%@://%@:%ld", + (_configuration.TLSEnabled ? @"s" : @""), _configuration.origin, _configuration.port]]; } - (NSDictionary *)defaultHeaders { NSString *device = @"iPhone"; -#if __IPHONE_OS_VERSION_MIN_REQUIRED +#if __IPHONE_OS_VERSION_MIN_REQUIRED || defined(PGDROID) device = [[UIDevice currentDevice] model]; NSString *osVersion = [[UIDevice currentDevice] systemVersion]; #elif __MAC_OS_X_VERSION_MIN_REQUIRED diff --git a/PubNub/Network/PNReachability.m b/PubNub/Network/PNReachability.m index 116beb6be..0c6a6f5ba 100644 --- a/PubNub/Network/PNReachability.m +++ b/PubNub/Network/PNReachability.m @@ -168,9 +168,13 @@ - (void)setPingRemoteService:(BOOL)pingRemoteService { - (void)startServicePing { if (!self.pingingRemoteService) { - self.pingRemoteService = YES; - + [self performServicePing]; + } +} + +- (void)performServicePing { + if (self.pingingRemoteService) { // Silence static analyzer warnings. // Code is aware about this case and at the end will simply call on 'nil' object method. // In most cases if referenced object become 'nil' it mean what there is no more need in @@ -181,6 +185,9 @@ - (void)startServicePing { // Try to request 'time' API to ensure what network really available. __weak __typeof(self) weakSelf = self; [self.client timeWithCompletion:^(PNTimeResult *result, __unused PNErrorStatus *status) { + if (!self.pingingRemoteService) { + return; + } __strong __typeof(self) strongSelf = weakSelf; BOOL successfulPing = (result.data != nil); @@ -201,9 +208,7 @@ - (void)startServicePing { NSTimeInterval delay = ((strongSelf.reachable && !successfulPing) ? 1.f : 10.0f); dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delay * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ - - strongSelf.pingRemoteService = NO; - [strongSelf startServicePing]; + [strongSelf performServicePing]; }); } strongSelf.reachable = successfulPing; diff --git a/PubNub/SConscript b/PubNub/SConscript new file mode 100644 index 000000000..0f1cff994 --- /dev/null +++ b/PubNub/SConscript @@ -0,0 +1,117 @@ +header_paths = [ + # Lumberingjack stuff + '../../Pods/CocoaLumberjack/Classes/', + '../../Pods/Headers/Public/', + + # PubNub + './Core', + './Data', + './Data/Managers', + './Data/Service Objects', + './Misc', + './Misc/Helpers', + './Misc/Logger', + './Misc/Protocols', + './Network', + './Network/Parsers', + './PubNub', + '.', +] + +defines = { + 'PGDROID' : 1, +} + +flags = [ + '-fobjc-arc', + '-Wall', + #'-Werror', ... sigh ... maybe someday +] + +deps = [ +] + +sources = [ + # Lumberingjack stuff + '../../Pods/CocoaLumberjack/Classes/DDASLLogCapture.m', + '../../Pods/CocoaLumberjack/Classes/DDASLLogger.m', + '../../Pods/CocoaLumberjack/Classes/DDAbstractDatabaseLogger.m', + '../../Pods/CocoaLumberjack/Classes/DDFileLogger.m', + '../../Pods/CocoaLumberjack/Classes/DDLog.m', + '../../Pods/CocoaLumberjack/Classes/DDTTYLogger.m', + + # PubNub stuffs + './Core/PubNub+APNS.m', + './Core/PubNub+ChannelGroup.m', + './Core/PubNub+Core.m', + './Core/PubNub+History.m', + './Core/PubNub+Presence.m', + './Core/PubNub+Publish.m', + './Core/PubNub+State.m', + './Core/PubNub+Subscribe.m', + './Core/PubNub+Time.m', + './Data/Managers/PNClientState.m', + './Data/Managers/PNHeartbeat.m', + './Data/Managers/PNStateListener.m', + './Data/Managers/PNSubscriber.m', + './Data/PNAES.m', + './Data/PNConfiguration.m', + './Data/Service Objects/PNAcknowledgmentStatus.m', + './Data/Service Objects/PNAPNSEnabledChannelsResult.m', + './Data/Service Objects/PNChannelClientStateResult.m', + './Data/Service Objects/PNChannelGroupChannelsResult.m', + './Data/Service Objects/PNChannelGroupClientStateResult.m', + './Data/Service Objects/PNChannelGroupsResult.m', + './Data/Service Objects/PNClientStateUpdateStatus.m', + './Data/Service Objects/PNErrorStatus.m', + './Data/Service Objects/PNHistoryResult.m', + './Data/Service Objects/PNPresenceChannelGroupHereNowResult.m', + './Data/Service Objects/PNPresenceChannelHereNowResult.m', + './Data/Service Objects/PNPresenceGlobalHereNowResult.m', + './Data/Service Objects/PNPresenceWhereNowResult.m', + './Data/Service Objects/PNPublishStatus.m', + './Data/Service Objects/PNResult.m', + './Data/Service Objects/PNServiceData.m', + './Data/Service Objects/PNStatus.m', + './Data/Service Objects/PNSubscriberResults.m', + './Data/Service Objects/PNSubscribeStatus.m', + './Data/Service Objects/PNTimeResult.m', + './Misc/Helpers/PNArray.m', + './Misc/Helpers/PNChannel.m', + './Misc/Helpers/PNClass.m', + './Misc/Helpers/PNData.m', + './Misc/Helpers/PNDictionary.m', + './Misc/Helpers/PNGZIP.m', + './Misc/Helpers/PNJSON.m', + './Misc/Helpers/PNString.m', + './Misc/Helpers/PNURLRequest.m', + './Misc/Logger/PNLog.m', + './Misc/Logger/PNLogFileManager.m', + './Misc/Logger/PNLogger.m', + './Network/Parsers/PNChannelGroupAuditionParser.m', + './Network/Parsers/PNChannelGroupModificationParser.m', + './Network/Parsers/PNClientStateParser.m', + './Network/Parsers/PNErrorParser.m', + './Network/Parsers/PNHeartbeatParser.m', + './Network/Parsers/PNHistoryParser.m', + './Network/Parsers/PNLeaveParser.m', + './Network/Parsers/PNMessagePublishParser.m', + './Network/Parsers/PNPresenceHereNowParser.m', + './Network/Parsers/PNPresenceWhereNowParser.m', + './Network/Parsers/PNPushNotificationsAuditParser.m', + './Network/Parsers/PNPushNotificationsStateModificationParser.m', + './Network/Parsers/PNRemoveDeviceFromAPNSResponseParser.m', + './Network/Parsers/PNSubscribeParser.m', + './Network/Parsers/PNTimeParser.m', + './Network/PNNetwork.m', + './Network/PNNetworkResponseSerializer.m', + './Network/PNReachability.m', + './Network/PNRequestParameters.m', + './Network/PNURLBuilder.m', +] + +features = [ +] + +Import('env') +env.BuildLibrary('PubNub', sources, header_paths=header_paths, static=True, flags=flags, defines=defines, deps=deps, features=features) diff --git a/src b/src new file mode 120000 index 000000000..bb49dac7b --- /dev/null +++ b/src @@ -0,0 +1 @@ +PubNub \ No newline at end of file