X-Git-Url: https://git.mdrn.pl/wl-app.git/blobdiff_plain/53b27422d140022594fc241cca91c3183be57bca..48b2fe9f7c2dc3d9aeaaa6dbfb27c7da4f3235ff:/iOS/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingTopicOperation.m diff --git a/iOS/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingTopicOperation.m b/iOS/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingTopicOperation.m new file mode 100644 index 0000000..6703178 --- /dev/null +++ b/iOS/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingTopicOperation.m @@ -0,0 +1,263 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRMessagingTopicOperation.h" + +#import "FIRMessagingCheckinService.h" +#import "FIRMessagingDefines.h" +#import "FIRMessagingLogger.h" +#import "FIRMessagingUtilities.h" +#import "NSError+FIRMessaging.h" + +#define DEBUG_LOG_SUBSCRIPTION_OPERATION_DURATIONS 0 + +static NSString *const kFIRMessagingSubscribeServerHost = + @"https://iid.googleapis.com/iid/register"; + +NSString *FIRMessagingSubscriptionsServer() { + static NSString *serverHost = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + NSDictionary *environment = [[NSProcessInfo processInfo] environment]; + NSString *customServerHost = environment[@"FCM_SERVER_ENDPOINT"]; + if (customServerHost.length) { + serverHost = customServerHost; + } else { + serverHost = kFIRMessagingSubscribeServerHost; + } + }); + return serverHost; +} + +@interface FIRMessagingTopicOperation () { + BOOL _isFinished; + BOOL _isExecuting; +} + +@property(nonatomic, readwrite, copy) NSString *topic; +@property(nonatomic, readwrite, assign) FIRMessagingTopicAction action; +@property(nonatomic, readwrite, copy) NSString *token; +@property(nonatomic, readwrite, copy) NSDictionary *options; +@property(nonatomic, readwrite, strong) FIRMessagingCheckinService *checkinService; +@property(nonatomic, readwrite, copy) FIRMessagingTopicOperationCompletion completion; + +@property(atomic, strong) NSURLSessionDataTask *dataTask; + +@end + +@implementation FIRMessagingTopicOperation + ++ (NSURLSession *)sharedSession { + static NSURLSession *subscriptionOperationSharedSession; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration]; + config.timeoutIntervalForResource = 60.0f; // 1 minute + subscriptionOperationSharedSession = [NSURLSession sessionWithConfiguration:config]; + subscriptionOperationSharedSession.sessionDescription = @"com.google.fcm.topics.session"; + }); + return subscriptionOperationSharedSession; +} + +- (instancetype)initWithTopic:(NSString *)topic + action:(FIRMessagingTopicAction)action + token:(NSString *)token + options:(NSDictionary *)options + checkinService:(FIRMessagingCheckinService *)checkinService + completion:(FIRMessagingTopicOperationCompletion)completion { + if (self = [super init]) { + _topic = topic; + _action = action; + _token = token; + _options = options; + _checkinService = checkinService; + _completion = completion; + + _isExecuting = NO; + _isFinished = NO; + } + return self; +} + +- (void)dealloc { + _topic = nil; + _token = nil; + _checkinService = nil; + _completion = nil; +} + +- (BOOL)isAsynchronous { + return YES; +} + +- (BOOL)isExecuting { + return _isExecuting; +} + +- (void)setExecuting:(BOOL)executing { + [self willChangeValueForKey:@"isExecuting"]; + _isExecuting = executing; + [self didChangeValueForKey:@"isExecuting"]; +} + +- (BOOL)isFinished { + return _isFinished; +} + +- (void)setFinished:(BOOL)finished { + [self willChangeValueForKey:@"isFinished"]; + _isFinished = finished; + [self didChangeValueForKey:@"isFinished"]; +} + +- (void)start { + if (self.isCancelled) { + NSError *error = + [NSError errorWithFCMErrorCode:kFIRMessagingErrorCodePubSubOperationIsCancelled]; + [self finishWithError:error]; + return; + } + + [self setExecuting:YES]; + + [self performSubscriptionChange]; +} + +- (void)finishWithError:(NSError *)error { + // Add a check to prevent this finish from being called more than once. + if (self.isFinished) { + return; + } + self.dataTask = nil; + if (self.completion) { + self.completion(error); + } + + [self setExecuting:NO]; + [self setFinished:YES]; +} + +- (void)cancel { + [super cancel]; + [self.dataTask cancel]; + NSError *error = [NSError errorWithFCMErrorCode:kFIRMessagingErrorCodePubSubOperationIsCancelled]; + [self finishWithError:error]; +} + +- (void)performSubscriptionChange { + + NSURL *url = [NSURL URLWithString:FIRMessagingSubscriptionsServer()]; + NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; + NSString *appIdentifier = FIRMessagingAppIdentifier(); + NSString *deviceAuthID = self.checkinService.deviceAuthID; + NSString *secretToken = self.checkinService.secretToken; + NSString *authString = [NSString stringWithFormat:@"AidLogin %@:%@", deviceAuthID, secretToken]; + [request setValue:authString forHTTPHeaderField:@"Authorization"]; + [request setValue:appIdentifier forHTTPHeaderField:@"app"]; + [request setValue:self.checkinService.versionInfo forHTTPHeaderField:@"info"]; + + // Topic can contain special characters (like `%`) so encode the value. + NSCharacterSet *characterSet = [NSCharacterSet URLQueryAllowedCharacterSet]; + NSString *encodedTopic = + [self.topic stringByAddingPercentEncodingWithAllowedCharacters:characterSet]; + if (encodedTopic == nil) { + // The transformation was somehow not possible, so use the original topic. + FIRMessagingLoggerWarn(kFIRMessagingMessageCodeTopicOptionTopicEncodingFailed, + @"Unable to encode the topic '%@' during topic subscription change. " + @"Please ensure that the topic name contains only valid characters.", + self.topic); + encodedTopic = self.topic; + } + + NSMutableString *content = [NSMutableString stringWithFormat: + @"sender=%@&app=%@&device=%@&" + @"app_ver=%@&X-gcm.topic=%@&X-scope=%@", + self.token, + appIdentifier, + deviceAuthID, + FIRMessagingCurrentAppVersion(), + encodedTopic, + encodedTopic]; + + if (self.action == FIRMessagingTopicActionUnsubscribe) { + [content appendString:@"&delete=true"]; + } + + FIRMessagingLoggerInfo(kFIRMessagingMessageCodeTopicOption000, @"Topic subscription request: %@", + content); + + request.HTTPBody = [content dataUsingEncoding:NSUTF8StringEncoding]; + [request setHTTPMethod:@"POST"]; + +#if DEBUG_LOG_SUBSCRIPTION_OPERATION_DURATIONS + NSDate *start = [NSDate date]; +#endif + + FIRMessaging_WEAKIFY(self) + void(^requestHandler)(NSData *, NSURLResponse *, NSError *) = + ^(NSData *data, NSURLResponse *URLResponse, NSError *error) { + FIRMessaging_STRONGIFY(self) + if (error) { + // Our operation could have been cancelled, which would result in our data task's error being + // NSURLErrorCancelled + if (error.code == NSURLErrorCancelled) { + // We would only have been cancelled in the -cancel method, which will call finish for us + // so just return and do nothing. + return; + } + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeTopicOption001, + @"Device registration HTTP fetch error. Error Code: %ld", + _FIRMessaging_L(error.code)); + [self finishWithError:error]; + return; + } + NSString *response = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + if (response.length == 0) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeTopicOperationEmptyResponse, + @"Invalid registration response - zero length."); + [self finishWithError:[NSError errorWithFCMErrorCode:kFIRMessagingErrorCodeUnknown]]; + return; + } + NSArray *parts = [response componentsSeparatedByString:@"="]; + _FIRMessagingDevAssert(parts.count, @"Invalid registration response"); + if (![parts[0] isEqualToString:@"token"] || parts.count <= 1) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeTopicOption002, + @"Invalid registration response %@", response); + [self finishWithError:[NSError errorWithFCMErrorCode:kFIRMessagingErrorCodeUnknown]]; + return; + } +#if DEBUG_LOG_SUBSCRIPTION_OPERATION_DURATIONS + NSTimeInterval duration = -[start timeIntervalSinceNow]; + FIRMessagingLoggerDebug(@"%@ change took %.2fs", self.topic, duration); +#endif + [self finishWithError:nil]; + + }; + + NSURLSession *urlSession = [FIRMessagingTopicOperation sharedSession]; + + self.dataTask = [urlSession dataTaskWithRequest:request completionHandler:requestHandler]; + NSString *description; + if (_action == FIRMessagingTopicActionSubscribe) { + description = [NSString stringWithFormat:@"com.google.fcm.topics.subscribe: %@", _topic]; + } else { + description = [NSString stringWithFormat:@"com.google.fcm.topics.unsubscribe: %@", _topic]; + } + self.dataTask.taskDescription = description; + [self.dataTask resume]; +} + +@end