Skip to content

Commit 6c6e706

Browse files
authored
Merge pull request #1034 from BranchMetrics/SDK-863-AppleTV
SDK-863 apple tv
2 parents 60c1d96 + 7609590 commit 6c6e706

File tree

18 files changed

+881
-113
lines changed

18 files changed

+881
-113
lines changed

Branch-SDK/Branch-SDK/BNCApplication.m

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -116,38 +116,48 @@ + (NSDate*) firstInstallBuildDate {
116116
return firstBuildDate;
117117
}
118118

119-
+ (NSDate*) currentInstallDate {
119+
+ (NSDate *) currentInstallDate {
120+
NSDate *installDate = [NSDate date];
121+
122+
#if !TARGET_OS_TV
123+
// tvOS always returns a creation date of Unix epoch 0 on device
124+
installDate = [self creationDateForLibraryDirectory];
125+
#endif
126+
127+
if (installDate == nil || [installDate timeIntervalSince1970] <= 0.0) {
128+
BNCLogWarning(@"Invalid install date, using [NSDate date].");
129+
}
130+
return installDate;
131+
}
132+
133+
+ (NSDate *)creationDateForLibraryDirectory {
120134
NSError *error = nil;
121135
NSFileManager *fileManager = [NSFileManager defaultManager];
122-
NSURL *libraryURL =
123-
[[fileManager URLsForDirectory:NSLibraryDirectory inDomains:NSUserDomainMask] firstObject];
124-
NSDictionary *attributes = [fileManager attributesOfItemAtPath:libraryURL.path error:&error];
136+
NSURL *directoryURL = [[fileManager URLsForDirectory:NSLibraryDirectory inDomains:NSUserDomainMask] firstObject];
137+
NSDictionary *attributes = [fileManager attributesOfItemAtPath:directoryURL.path error:&error];
125138
if (error) {
126-
BNCLogError(@"Can't get library date: %@.", error);
127-
return nil;
128-
}
129-
NSDate *installDate = [attributes fileCreationDate];
130-
if (installDate == nil || [installDate timeIntervalSince1970] <= 0.0) {
131-
BNCLogError(@"Invalid install date.");
139+
BNCLogError(@"Can't get creation date for Library directory: %@", error);
140+
return nil;
132141
}
133-
return installDate;
142+
return [attributes fileCreationDate];
134143
}
135144

136145
+ (NSDate*) firstInstallDate {
146+
// check keychain for stored install date, on iOS this is lost on app deletion.
137147
NSError *error = nil;
138-
NSDate* firstInstallDate =
139-
[BNCKeyChain retrieveValueForService:kBranchKeychainService
140-
key:kBranchKeychainFirstInstalldKey
141-
error:&error];
142-
if (firstInstallDate)
148+
NSDate* firstInstallDate = [BNCKeyChain retrieveValueForService:kBranchKeychainService key:kBranchKeychainFirstInstalldKey error:&error];
149+
if (firstInstallDate) {
143150
return firstInstallDate;
144-
151+
}
152+
153+
// check filesytem for creation date
145154
firstInstallDate = [self currentInstallDate];
146-
error = [BNCKeyChain storeValue:firstInstallDate
147-
forService:kBranchKeychainService
148-
key:kBranchKeychainFirstInstalldKey
149-
cloudAccessGroup:nil];
150-
if (error) BNCLogError(@"Keychain store: %@.", error);
155+
156+
// save filesystem time to keychain
157+
error = [BNCKeyChain storeValue:firstInstallDate forService:kBranchKeychainService key:kBranchKeychainFirstInstalldKey cloudAccessGroup:nil];
158+
if (error) {
159+
BNCLogError(@"Keychain store: %@.", error);
160+
}
151161
return firstInstallDate;
152162
}
153163

Branch-SDK/Branch-SDK/BNCDeviceInfo.m

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,17 @@
1212
#import "BNCLog.h"
1313
#import "BNCConfig.h"
1414
#import "BNCNetworkInterface.h"
15-
#import "BNCUserAgentCollector.h"
16-
#import "BNCTelephony.h"
1715
#import "BNCReachability.h"
1816
#import "BNCLocale.h"
1917
#import "NSMutableDictionary+Branch.h"
2018
#import "BNCDeviceSystem.h"
2119

20+
#if !TARGET_OS_TV
21+
// tvOS does not support webkit or telephony
22+
#import "BNCTelephony.h"
23+
#import "BNCUserAgentCollector.h"
24+
#endif
25+
2226
#if __has_feature(modules)
2327
@import UIKit;
2428
#else
@@ -60,31 +64,34 @@ - (void)registerPluginName:(NSString *)name version:(NSString *)version {
6064
}
6165

6266
- (void)loadDeviceInfo {
63-
67+
6468
BNCLocale *locale = [BNCLocale new];
65-
BNCTelephony *telephony = [BNCTelephony new];
6669
BNCDeviceSystem *deviceSystem = [BNCDeviceSystem new];
67-
70+
6871
// The random id is regenerated per app launch. This maintains existing behavior.
6972
self.randomId = [[NSUUID UUID] UUIDString];
7073
self.vendorId = [BNCSystemObserver getVendorId];
7174
[self checkAdvertisingIdentifier];
72-
75+
7376
self.brandName = [BNCSystemObserver getBrand];
7477
self.modelName = [BNCSystemObserver getModel];
7578
self.osName = [BNCSystemObserver getOS];
7679
self.osVersion = [BNCSystemObserver getOSVersion];
7780
self.osBuildVersion = deviceSystem.systemBuildVersion;
78-
81+
7982
if (deviceSystem.cpuType) {
8083
self.cpuType = [deviceSystem.cpuType stringValue];
8184
}
82-
85+
8386
self.screenWidth = [BNCSystemObserver getScreenWidth];
8487
self.screenHeight = [BNCSystemObserver getScreenHeight];
8588
self.screenScale = @([UIScreen mainScreen].scale);
89+
90+
#if !TARGET_OS_TV
91+
BNCTelephony *telephony = [BNCTelephony new];
8692
self.carrierName = telephony.carrierName;
87-
93+
#endif
94+
8895
self.locale = [NSLocale currentLocale].localeIdentifier;
8996
self.country = [locale country];
9097
self.language = [locale language];
@@ -114,25 +121,30 @@ - (NSString *)connectionType {
114121
}
115122

116123
- (NSString *)userAgentString {
124+
#if !TARGET_OS_TV
117125
return [BNCUserAgentCollector instance].userAgent;
126+
#else
127+
// tvOS has no web browser or webview
128+
return @"";
129+
#endif
118130
}
119131

120132
// IDFA should never be cached
121133
- (void)checkAdvertisingIdentifier {
122134
self.isAdTrackingEnabled = [BNCSystemObserver adTrackingSafe];
123135
self.advertiserId = [BNCSystemObserver getAdId];
124136
BOOL ignoreIdfa = [BNCPreferenceHelper preferenceHelper].isDebug;
125-
137+
126138
if (self.advertiserId && !ignoreIdfa) {
127139
self.hardwareId = self.advertiserId;
128140
self.hardwareIdType = @"idfa";
129141
self.isRealHardwareId = YES;
130-
142+
131143
} else if (self.vendorId) {
132144
self.hardwareId = self.vendorId;
133145
self.hardwareIdType = @"vendor_id";
134146
self.isRealHardwareId = YES;
135-
147+
136148
} else {
137149
self.hardwareId = self.randomId;
138150
self.hardwareIdType = @"random";
@@ -144,24 +156,24 @@ - (NSDictionary *)v2dictionary {
144156
NSMutableDictionary *dictionary = [NSMutableDictionary new];
145157
@synchronized (self) {
146158
[self checkAdvertisingIdentifier];
147-
159+
148160
BOOL disableAdNetworkCallouts = [BNCPreferenceHelper preferenceHelper].disableAdNetworkCallouts;
149161
if (disableAdNetworkCallouts) {
150162
dictionary[@"disable_ad_network_callouts"] = [NSNumber numberWithBool:disableAdNetworkCallouts];
151163
}
152-
164+
153165
if ([BNCPreferenceHelper preferenceHelper].isDebug) {
154166
dictionary[@"unidentified_device"] = @(YES);
155167
} else {
156168
[dictionary bnc_safeSetObject:self.vendorId forKey:@"idfv"];
157169
[dictionary bnc_safeSetObject:self.advertiserId forKey:@"idfa"];
158170
}
159171
[dictionary bnc_safeSetObject:[self localIPAddress] forKey:@"local_ip"];
160-
172+
161173
if (!self.isAdTrackingEnabled) {
162174
dictionary[@"limit_ad_tracking"] = @(YES);
163175
}
164-
176+
165177
if ([BNCPreferenceHelper preferenceHelper].limitFacebookTracking) {
166178
dictionary[@"limit_facebook_tracking"] = @(YES);
167179
}
@@ -184,9 +196,9 @@ - (NSDictionary *)v2dictionary {
184196

185197
[dictionary bnc_safeSetObject:[BNCPreferenceHelper preferenceHelper].userIdentity forKey:@"developer_identity"];
186198
[dictionary bnc_safeSetObject:[BNCPreferenceHelper preferenceHelper].deviceFingerprintID forKey:@"device_fingerprint_id"];
187-
199+
188200
[dictionary bnc_safeSetObject:self.applicationVersion forKey:@"app_version"];
189-
201+
190202
[dictionary bnc_safeSetObject:self.pluginName forKey:@"plugin_name"];
191203
[dictionary bnc_safeSetObject:self.pluginVersion forKey:@"plugin_version"];
192204
dictionary[@"sdk_version"] = BNC_SDK_VERSION;

Branch-SDK/Branch-SDK/BNCLocale.m

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ - (nullable NSString *)country {
2626

2727
- (nullable NSString *)countryOS10 {
2828
NSString *country = nil;
29-
if (@available(iOS 10, *)) {
29+
if (@available(iOS 10, tvOS 10, *)) {
3030
country = [[NSLocale currentLocale] countryCode];
3131
}
3232
return country;
@@ -63,15 +63,15 @@ - (nullable NSString *)language {
6363

6464
- (nullable NSString *)languageOS10 {
6565
NSString *language = nil;
66-
if (@available(iOS 10, *)) {
66+
if (@available(iOS 10, tvOS 10, *)) {
6767
language = [[NSLocale currentLocale] languageCode];
6868
}
6969
return language;
7070
}
7171

7272
- (nullable NSString *)languageOS9 {
7373
NSString *language = nil;
74-
if (@available(iOS 9, *)) {
74+
if (@available(iOS 9, tvOS 9, *)) {
7575
NSString *rawLanguage = [[NSLocale preferredLanguages] firstObject];
7676
NSDictionary *languageDictionary = [NSLocale componentsFromLocaleIdentifier:rawLanguage];
7777
language = [languageDictionary objectForKey:@"kCFLocaleLanguageCodeKey"];

Branch-SDK/Branch-SDK/BNCPreferenceHelper.m

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -911,27 +911,35 @@ + (void) initialize {
911911
if (success) {
912912
return branchURL;
913913
} else {
914-
BNCLogWarning(@"CreateBranchURL failed: %@ URL: %@.", error, branchURL);
914+
// BNCLog is dependent on BNCCreateDirectoryForBranchURLWithSearchPath_Unthreaded and cannot be used to log errors from it.
915+
NSLog(@"CreateBranchURL failed: %@ URL: %@.", error, branchURL);
915916
}
916917
}
917918
return nil;
918919
}
919920

920921
NSURL* _Nonnull BNCURLForBranchDirectory_Unthreaded() {
922+
#if TARGET_OS_TV
923+
// tvOS only allows the caches or temp directory
924+
NSArray *kSearchDirectories = @[
925+
@(NSCachesDirectory)
926+
];
927+
#else
921928
NSArray *kSearchDirectories = @[
922929
@(NSApplicationSupportDirectory),
923930
@(NSLibraryDirectory),
924931
@(NSCachesDirectory),
925932
@(NSDocumentDirectory),
926933
];
927-
934+
#endif
935+
928936
for (NSNumber *directory in kSearchDirectories) {
929937
NSSearchPathDirectory directoryValue = [directory unsignedLongValue];
930938
NSURL *URL = BNCCreateDirectoryForBranchURLWithSearchPath_Unthreaded(directoryValue);
931939
if (URL) return URL;
932940
}
933941

934-
// Worst case backup plan:
942+
// Worst case backup plan. This does NOT work on tvOS.
935943
NSString *path = [@"~/Library/io.branch" stringByExpandingTildeInPath];
936944
NSURL *branchURL = [NSURL fileURLWithPath:path isDirectory:YES];
937945
NSFileManager *fileManager = [NSFileManager defaultManager];
@@ -943,7 +951,8 @@ + (void) initialize {
943951
attributes:nil
944952
error:&error];
945953
if (!success) {
946-
BNCLogError(@"Worst case CreateBranchURL error was: %@ URL: %@.", error, branchURL);
954+
// BNCLog is dependent on BNCURLForBranchDirectory_Unthreaded and cannot be used to log errors from it.
955+
NSLog(@"Worst case CreateBranchURL error was: %@ URL: %@.", error, branchURL);
947956
}
948957
return branchURL;
949958
}

Branch-SDK/Branch-SDK/BNCSystemObserver.m

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,11 @@ + (BOOL)isSimulator {
142142
}
143143

144144
+ (NSString *)getOS {
145+
#if TARGET_OS_TV
146+
return @"tv_OS";
147+
#else
145148
return @"iOS";
149+
#endif
146150
}
147151

148152
+ (NSString *)getOSVersion {

Branch-SDK/Branch-SDK/Branch.h

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,8 @@
88

99
#if __has_feature(modules)
1010
@import Foundation;
11-
@import UIKit;
1211
#else
1312
#import <Foundation/Foundation.h>
14-
#import <UIKit/UIKit.h>
1513
#endif
1614

1715
#import "BNCCallbacks.h"
@@ -25,21 +23,25 @@
2523
#import "BNCServerInterface.h"
2624
#import "BNCServerRequestQueue.h"
2725
#import "BNCAvailability.h"
28-
#import "BranchActivityItemProvider.h"
2926
#import "BranchConstants.h"
30-
#import "BranchCSSearchableItemAttributeSet.h"
3127
#import "BranchDeepLinkingController.h"
3228
#import "BranchEvent.h"
3329
#import "BranchLinkProperties.h"
3430
#import "BranchDelegate.h"
35-
#import "BranchShareLink.h"
3631
#import "BranchUniversalObject.h"
3732
#import "BranchCrossPlatformID.h"
3833
#import "BranchLastAttributedTouchData.h"
3934
#import "BNCInitSessionResponse.h"
4035
#import "UIViewController+Branch.h"
4136
#import "BranchScene.h"
4237

38+
#if !TARGET_OS_TV
39+
// tvOS does not support these features
40+
#import "BranchShareLink.h"
41+
#import "BranchActivityItemProvider.h"
42+
#import "BranchCSSearchableItemAttributeSet.h"
43+
#endif
44+
4345
NS_ASSUME_NONNULL_BEGIN
4446

4547
/**
@@ -277,7 +279,7 @@ typedef NS_ENUM(NSUInteger, BranchCreditHistoryOrder) {
277279
@property (weak, nullable) NSObject<BranchDelegate>* delegate;
278280

279281
#pragma mark - BranchActivityItemProvider methods
280-
282+
#if !TARGET_OS_TV
281283
///-----------------------------------------
282284
/// @name BranchActivityItemProvider methods
283285
///-----------------------------------------
@@ -366,7 +368,7 @@ typedef NS_ENUM(NSUInteger, BranchCreditHistoryOrder) {
366368
*/
367369
+ (BranchActivityItemProvider *)getBranchActivityItemWithParams:(NSDictionary *)params feature:(nullable NSString *)feature stage:(nullable NSString *)stage tags:(nullable NSArray *)tags alias:(nullable NSString *)alias delegate:(nullable id <BranchActivityItemProviderDelegate>)delegate;
368370

369-
371+
#endif
370372

371373
#pragma mark - Initialization methods
372374

@@ -1576,6 +1578,7 @@ typedef NS_ENUM(NSUInteger, BranchCreditHistoryOrder) {
15761578
- (void)getSpotlightUrlWithParams:(NSDictionary *)params callback:(callbackWithParams)callback;
15771579

15781580
#pragma mark - Content Discovery methods
1581+
#if !TARGET_OS_TV
15791582

15801583
///--------------------------------
15811584
/// @name Content Discovery methods
@@ -1829,6 +1832,8 @@ typedef NS_ENUM(NSUInteger, BranchCreditHistoryOrder) {
18291832
*/
18301833
- (void)removeAllPrivateContentFromSpotLightWithCallback:(void (^_Nullable)(NSError * _Nullable error))completion;
18311834

1835+
#endif
1836+
18321837
/**
18331838
Method for creating a one of Branch instance and specifying its dependencies.
18341839

0 commit comments

Comments
 (0)