From b8d806516d3b74ebf8added6b64b374ecddc5c97 Mon Sep 17 00:00:00 2001 From: Jean Regisser Date: Mon, 22 Oct 2018 12:13:25 +0200 Subject: [PATCH 1/2] Fix crash on iOS < 10 as NSISO8601DateFormatter is unavailable there This lead to trying to insert nil strings in the dictionary and causing the crash. --- ios/RCPurchaserInfo+RNPurchases.m | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/ios/RCPurchaserInfo+RNPurchases.m b/ios/RCPurchaserInfo+RNPurchases.m index 309696ba..59edd29a 100644 --- a/ios/RCPurchaserInfo+RNPurchases.m +++ b/ios/RCPurchaserInfo+RNPurchases.m @@ -8,25 +8,43 @@ #import "RCPurchaserInfo+RNPurchases.h" +static id formatter; +static dispatch_once_t onceToken; + +static NSString * stringFromDate(NSDate *date) +{ + dispatch_once(&onceToken, ^{ + if (@available(iOS 10.0, *)) { + formatter = [NSISO8601DateFormatter new]; + } else { + NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; + dateFormatter.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"GMT"]; + dateFormatter.dateFormat = @"yyyy-MM-dd'T'HH:mm:ss'Z'"; + dateFormatter.locale = [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"]; + formatter = dateFormatter; + } + }); + + return [formatter stringFromDate:date]; +} + @implementation RCPurchaserInfo (RNPurchases) - (NSDictionary *)dictionary { - NSISO8601DateFormatter *formatter = [NSISO8601DateFormatter new]; - NSMutableDictionary *allExpirations = [NSMutableDictionary new]; for (NSString *productIdentifier in self.allPurchasedProductIdentifiers) { NSDate *date = [self expirationDateForProductIdentifier:productIdentifier]; - allExpirations[productIdentifier] = date ? [formatter stringFromDate:date] : [NSNull null]; + allExpirations[productIdentifier] = stringFromDate(date) ?: [NSNull null]; } NSMutableDictionary *expirationsForActiveEntitlements = [NSMutableDictionary new]; for (NSString *entId in self.activeEntitlements) { NSDate *date = [self expirationDateForEntitlement:entId]; - expirationsForActiveEntitlements[entId] = date ? [formatter stringFromDate:date] : [NSNull null];; + expirationsForActiveEntitlements[entId] = stringFromDate(date) ?: [NSNull null];; } - id latestExpiration = self.latestExpirationDate ? [formatter stringFromDate:self.latestExpirationDate] : [NSNull null]; + id latestExpiration = stringFromDate(self.latestExpirationDate) ?: [NSNull null]; return @{ @"activeEntitlements": self.activeEntitlements.allObjects, From e039423f49fb37bfc80ac4e3cc1f3e111712d1aa Mon Sep 17 00:00:00 2001 From: Jean Regisser Date: Thu, 25 Oct 2018 09:30:48 +0200 Subject: [PATCH 2/2] Use NSDateFormatter on all iOS versions to keep the code simple --- ios/RCPurchaserInfo+RNPurchases.m | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/ios/RCPurchaserInfo+RNPurchases.m b/ios/RCPurchaserInfo+RNPurchases.m index 59edd29a..671d5723 100644 --- a/ios/RCPurchaserInfo+RNPurchases.m +++ b/ios/RCPurchaserInfo+RNPurchases.m @@ -8,21 +8,18 @@ #import "RCPurchaserInfo+RNPurchases.h" -static id formatter; +static NSDateFormatter *formatter; static dispatch_once_t onceToken; static NSString * stringFromDate(NSDate *date) { dispatch_once(&onceToken, ^{ - if (@available(iOS 10.0, *)) { - formatter = [NSISO8601DateFormatter new]; - } else { - NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; - dateFormatter.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"GMT"]; - dateFormatter.dateFormat = @"yyyy-MM-dd'T'HH:mm:ss'Z'"; - dateFormatter.locale = [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"]; - formatter = dateFormatter; - } + // Here we're not using NSISO8601DateFormatter as we need to support iOS < 10 + NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; + dateFormatter.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"GMT"]; + dateFormatter.dateFormat = @"yyyy-MM-dd'T'HH:mm:ss'Z'"; + dateFormatter.locale = [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"]; + formatter = dateFormatter; }); return [formatter stringFromDate:date];