/FBSDKCoreKit/FBSDKCoreKit/FBSDKSettings.m

http://github.com/facebook/facebook-ios-sdk · Objective C · 382 lines · 304 code · 54 blank · 24 comment · 37 complexity · b5745f5988ddf691d6893c4778375d78 MD5 · raw file

  1. // Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
  2. //
  3. // You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
  4. // copy, modify, and distribute this software in source code or binary form for use
  5. // in connection with the web services and APIs provided by Facebook.
  6. //
  7. // As with any software that integrates with the Facebook platform, your use of
  8. // this software is subject to the Facebook Developer Principles and Policies
  9. // [http://developers.facebook.com/policy/]. This copyright notice shall be
  10. // included in all copies or substantial portions of the software.
  11. //
  12. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  13. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  14. // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  15. // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  16. // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  17. // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  18. #import "FBSDKSettings+Internal.h"
  19. #import "FBSDKAccessTokenCache.h"
  20. #import "FBSDKAccessTokenExpirer.h"
  21. #import "FBSDKAppEvents+Internal.h"
  22. #import "FBSDKCoreKit.h"
  23. #define FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(TYPE, PLIST_KEY, GETTER, SETTER, DEFAULT_VALUE, ENABLE_CACHE) \
  24. static TYPE *g_##PLIST_KEY = nil; \
  25. + (TYPE *)GETTER \
  26. { \
  27. if ((g_##PLIST_KEY == nil) && ENABLE_CACHE) { \
  28. g_##PLIST_KEY = [[[NSUserDefaults standardUserDefaults] objectForKey:@#PLIST_KEY] copy]; \
  29. } \
  30. if (g_##PLIST_KEY == nil) { \
  31. g_##PLIST_KEY = [[[NSBundle mainBundle] objectForInfoDictionaryKey:@#PLIST_KEY] copy] ?: DEFAULT_VALUE; \
  32. } \
  33. return g_##PLIST_KEY; \
  34. } \
  35. + (void)SETTER:(TYPE *)value { \
  36. g_##PLIST_KEY = [value copy]; \
  37. if (ENABLE_CACHE) { \
  38. if (value != nil) { \
  39. [[NSUserDefaults standardUserDefaults] setObject:value forKey:@#PLIST_KEY]; \
  40. } else { \
  41. [[NSUserDefaults standardUserDefaults] removeObjectForKey:@#PLIST_KEY]; \
  42. } \
  43. } \
  44. [FBSDKSettings _logIfSDKSettingsChanged]; \
  45. }
  46. FBSDKLoggingBehavior FBSDKLoggingBehaviorAccessTokens = @"include_access_tokens";
  47. FBSDKLoggingBehavior FBSDKLoggingBehaviorPerformanceCharacteristics = @"perf_characteristics";
  48. FBSDKLoggingBehavior FBSDKLoggingBehaviorAppEvents = @"app_events";
  49. FBSDKLoggingBehavior FBSDKLoggingBehaviorInformational = @"informational";
  50. FBSDKLoggingBehavior FBSDKLoggingBehaviorCacheErrors = @"cache_errors";
  51. FBSDKLoggingBehavior FBSDKLoggingBehaviorUIControlErrors = @"ui_control_errors";
  52. FBSDKLoggingBehavior FBSDKLoggingBehaviorDeveloperErrors = @"developer_errors";
  53. FBSDKLoggingBehavior FBSDKLoggingBehaviorGraphAPIDebugWarning = @"graph_api_debug_warning";
  54. FBSDKLoggingBehavior FBSDKLoggingBehaviorGraphAPIDebugInfo = @"graph_api_debug_info";
  55. FBSDKLoggingBehavior FBSDKLoggingBehaviorNetworkRequests = @"network_requests";
  56. static NSObject<FBSDKAccessTokenCaching> *g_tokenCache;
  57. static NSMutableSet<FBSDKLoggingBehavior> *g_loggingBehaviors;
  58. static NSString *const FBSDKSettingsLimitEventAndDataUsage = @"com.facebook.sdk:FBSDKSettingsLimitEventAndDataUsage";
  59. static NSString *const FBSDKSettingsBitmask = @"com.facebook.sdk:FBSDKSettingsBitmask";
  60. static BOOL g_disableErrorRecovery;
  61. static NSString *g_userAgentSuffix;
  62. static NSString *g_defaultGraphAPIVersion;
  63. static FBSDKAccessTokenExpirer *g_accessTokenExpirer;
  64. //
  65. // Warning messages for App Event Flags
  66. //
  67. static NSString *const autoLogAppEventsEnabledNotSetWarning =
  68. @"<Warning>: Please set a value for FacebookAutoLogAppEventsEnabled. Set the flag to TRUE if you want "
  69. "to collect app install, app launch and in-app purchase events automatically. To request user consent "
  70. "before collecting data, set the flag value to FALSE, then change to TRUE once user consent is received. "
  71. "Learn more: https://developers.facebook.com/docs/app-events/getting-started-app-events-ios#disable-auto-events.";
  72. static NSString *const advertiserIDCollectionEnabledNotSetWarning =
  73. @"<Warning>: You haven't set a value for FacebookAdvertiserIDCollectionEnabled. Set the flag to TRUE if "
  74. "you want to collect Advertiser ID for better advertising and analytics results.";
  75. static NSString *const advertiserIDCollectionEnabledFalseWarning =
  76. @"<Warning>: The value for FacebookAdvertiserIDCollectionEnabled is currently set to FALSE so you're sending app "
  77. "events without collecting Advertiser ID. This can affect the quality of your advertising and analytics results.";
  78. @implementation FBSDKSettings
  79. + (void)initialize
  80. {
  81. if (self == [FBSDKSettings class]) {
  82. g_tokenCache = [[FBSDKAccessTokenCache alloc] init];
  83. g_accessTokenExpirer = [[FBSDKAccessTokenExpirer alloc] init];
  84. [FBSDKSettings _logWarnings];
  85. [FBSDKSettings _logIfSDKSettingsChanged];
  86. }
  87. }
  88. #pragma mark - Plist Configuration Settings
  89. FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSString, FacebookAppID, appID, setAppID, nil, NO);
  90. FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSString, FacebookUrlSchemeSuffix, appURLSchemeSuffix, setAppURLSchemeSuffix, nil, NO);
  91. FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSString, FacebookClientToken, clientToken, setClientToken, nil, NO);
  92. FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSString, FacebookDisplayName, displayName, setDisplayName, nil, NO);
  93. FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSString, FacebookDomainPart, facebookDomainPart, setFacebookDomainPart, nil, NO);
  94. FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSNumber, FacebookJpegCompressionQuality, _JPEGCompressionQualityNumber, _setJPEGCompressionQualityNumber, @0.9, NO);
  95. FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSNumber, FacebookAutoInitEnabled, _autoInitEnabled, _setAutoInitEnabled, @1, YES);
  96. FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSNumber, FacebookInstrumentEnabled, _instrumentEnabled, _setInstrumentEnabled, @1, YES);
  97. FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSNumber, FacebookAutoLogAppEventsEnabled, _autoLogAppEventsEnabled, _setAutoLogAppEventsEnabled, @1, YES);
  98. FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSNumber, FacebookAdvertiserIDCollectionEnabled, _advertiserIDCollectionEnabled, _setAdvertiserIDCollectionEnabled, @1, YES);
  99. FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSNumber, FacebookCodelessDebugLogEnabled, _codelessDebugLogEnabled,
  100. _setCodelessDebugLogEnabled, @0, YES);
  101. + (BOOL)isGraphErrorRecoveryEnabled
  102. {
  103. return !g_disableErrorRecovery;
  104. }
  105. + (void)setGraphErrorRecoveryEnabled:(BOOL)graphErrorRecoveryEnabled
  106. {
  107. g_disableErrorRecovery = !graphErrorRecoveryEnabled;
  108. }
  109. + (CGFloat)JPEGCompressionQuality
  110. {
  111. return [self _JPEGCompressionQualityNumber].floatValue;
  112. }
  113. + (void)setJPEGCompressionQuality:(CGFloat)JPEGCompressionQuality
  114. {
  115. [self _setJPEGCompressionQualityNumber:@(JPEGCompressionQuality)];
  116. }
  117. + (BOOL)isAutoInitEnabled
  118. {
  119. return [self _autoInitEnabled].boolValue;
  120. }
  121. + (void)setAutoInitEnabled:(BOOL)autoInitEnabled
  122. {
  123. [self _setAutoInitEnabled:@(autoInitEnabled)];
  124. if (autoInitEnabled) {
  125. [FBSDKApplicationDelegate initializeSDK:nil];
  126. }
  127. }
  128. + (BOOL)isInstrumentEnabled
  129. {
  130. return [self _instrumentEnabled].boolValue;
  131. }
  132. + (void)setInstrumentEnabled:(BOOL)instrumentEnabled
  133. {
  134. [self _setInstrumentEnabled:@(instrumentEnabled)];
  135. }
  136. + (BOOL)isCodelessDebugLogEnabled
  137. {
  138. return [self _codelessDebugLogEnabled].boolValue;
  139. }
  140. + (void)setCodelessDebugLogEnabled:(BOOL)codelessDebugLogEnabled
  141. {
  142. [self _setCodelessDebugLogEnabled:@(codelessDebugLogEnabled)];
  143. }
  144. + (BOOL)isAutoLogAppEventsEnabled
  145. {
  146. return [self _autoLogAppEventsEnabled].boolValue;
  147. }
  148. + (void)setAutoLogAppEventsEnabled:(BOOL)autoLogAppEventsEnabled
  149. {
  150. [self _setAutoLogAppEventsEnabled:@(autoLogAppEventsEnabled)];
  151. }
  152. + (BOOL)isAdvertiserIDCollectionEnabled
  153. {
  154. return [self _advertiserIDCollectionEnabled].boolValue;
  155. }
  156. + (void)setAdvertiserIDCollectionEnabled:(BOOL)advertiserIDCollectionEnabled
  157. {
  158. [self _setAdvertiserIDCollectionEnabled:@(advertiserIDCollectionEnabled)];
  159. }
  160. + (BOOL)shouldLimitEventAndDataUsage
  161. {
  162. NSNumber *storedValue = [[NSUserDefaults standardUserDefaults] objectForKey:FBSDKSettingsLimitEventAndDataUsage];
  163. if (storedValue == nil) {
  164. return NO;
  165. }
  166. return storedValue.boolValue;
  167. }
  168. + (void)setLimitEventAndDataUsage:(BOOL)limitEventAndDataUsage
  169. {
  170. NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
  171. [defaults setObject:@(limitEventAndDataUsage) forKey:FBSDKSettingsLimitEventAndDataUsage];
  172. [defaults synchronize];
  173. }
  174. + (NSSet<FBSDKLoggingBehavior> *)loggingBehaviors
  175. {
  176. if (!g_loggingBehaviors) {
  177. NSArray<FBSDKLoggingBehavior> *bundleLoggingBehaviors = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"FacebookLoggingBehavior"];
  178. if (bundleLoggingBehaviors) {
  179. g_loggingBehaviors = [[NSMutableSet alloc] initWithArray:bundleLoggingBehaviors];
  180. } else {
  181. // Establish set of default enabled logging behaviors. You can completely disable logging by
  182. // specifying an empty array for FacebookLoggingBehavior in your Info.plist.
  183. g_loggingBehaviors = [[NSMutableSet alloc] initWithObjects:FBSDKLoggingBehaviorDeveloperErrors, nil];
  184. }
  185. }
  186. return [g_loggingBehaviors copy];
  187. }
  188. + (void)setLoggingBehaviors:(NSSet<FBSDKLoggingBehavior> *)loggingBehaviors
  189. {
  190. if (![g_loggingBehaviors isEqualToSet:loggingBehaviors]) {
  191. g_loggingBehaviors = [loggingBehaviors mutableCopy];
  192. [self updateGraphAPIDebugBehavior];
  193. }
  194. }
  195. + (void)enableLoggingBehavior:(FBSDKLoggingBehavior)loggingBehavior
  196. {
  197. if (!g_loggingBehaviors) {
  198. [self loggingBehaviors];
  199. }
  200. [g_loggingBehaviors addObject:loggingBehavior];
  201. [self updateGraphAPIDebugBehavior];
  202. }
  203. + (void)disableLoggingBehavior:(FBSDKLoggingBehavior)loggingBehavior
  204. {
  205. if (!g_loggingBehaviors) {
  206. [self loggingBehaviors];
  207. }
  208. [g_loggingBehaviors removeObject:loggingBehavior];
  209. [self updateGraphAPIDebugBehavior];
  210. }
  211. #pragma mark - Readonly Configuration Settings
  212. + (NSString *)sdkVersion
  213. {
  214. return FBSDK_VERSION_STRING;
  215. }
  216. #pragma mark - Internal
  217. + (NSObject<FBSDKAccessTokenCaching> *)accessTokenCache
  218. {
  219. return g_tokenCache;
  220. }
  221. + (void)setAccessTokenCache:(NSObject<FBSDKAccessTokenCaching> *)cache
  222. {
  223. if (g_tokenCache != cache) {
  224. g_tokenCache = cache;
  225. }
  226. }
  227. + (NSString *)userAgentSuffix
  228. {
  229. return g_userAgentSuffix;
  230. }
  231. + (void)setUserAgentSuffix:(NSString *)suffix
  232. {
  233. if (![g_userAgentSuffix isEqualToString:suffix]) {
  234. g_userAgentSuffix = suffix;
  235. }
  236. }
  237. + (void)setGraphAPIVersion:(NSString *)version
  238. {
  239. if (![g_defaultGraphAPIVersion isEqualToString:version])
  240. {
  241. g_defaultGraphAPIVersion = version;
  242. }
  243. }
  244. + (NSString *)defaultGraphAPIVersion
  245. {
  246. return FBSDK_TARGET_PLATFORM_VERSION;
  247. }
  248. + (NSString *)graphAPIVersion
  249. {
  250. return g_defaultGraphAPIVersion ?: self.defaultGraphAPIVersion;
  251. }
  252. + (NSNumber *)appEventSettingsForPlistKey:(NSString *)plistKey
  253. defaultValue:(NSNumber *)defaultValue
  254. {
  255. return [[[NSBundle mainBundle] objectForInfoDictionaryKey:plistKey] copy] ?: defaultValue;
  256. }
  257. + (NSNumber *)appEventSettingsForUserDefaultsKey:(NSString *)userDefaultsKey
  258. defaultValue:(NSNumber *)defaultValue
  259. {
  260. NSData *data = [[NSUserDefaults standardUserDefaults] objectForKey:userDefaultsKey];
  261. if ([data isKindOfClass:[NSNumber class]]) {
  262. return (NSNumber *)data;
  263. }
  264. return defaultValue;
  265. }
  266. + (void)_logWarnings
  267. {
  268. NSBundle *mainBundle = [NSBundle mainBundle];
  269. // Log warnings for App Event Flags
  270. if (![mainBundle objectForInfoDictionaryKey:@"FacebookAutoLogAppEventsEnabled"]) {
  271. NSLog(autoLogAppEventsEnabledNotSetWarning);
  272. }
  273. if (![mainBundle objectForInfoDictionaryKey:@"FacebookAdvertiserIDCollectionEnabled"]) {
  274. NSLog(advertiserIDCollectionEnabledNotSetWarning);
  275. }
  276. if (![FBSDKSettings isAdvertiserIDCollectionEnabled]) {
  277. NSLog(advertiserIDCollectionEnabledFalseWarning);
  278. }
  279. }
  280. + (void)_logIfSDKSettingsChanged
  281. {
  282. NSInteger bitmask = 0;
  283. NSInteger bit = 0;
  284. bitmask |= ([FBSDKSettings isAutoInitEnabled] ? 1 : 0) << bit++;
  285. bitmask |= ([FBSDKSettings isAutoLogAppEventsEnabled] ? 1 : 0) << bit++;
  286. bitmask |= ([FBSDKSettings isAdvertiserIDCollectionEnabled] ? 1 : 0) << bit++;
  287. NSInteger previousBitmask = [[NSUserDefaults standardUserDefaults] integerForKey:FBSDKSettingsBitmask];
  288. if (previousBitmask != bitmask) {
  289. [[NSUserDefaults standardUserDefaults] setInteger:bitmask forKey:FBSDKSettingsBitmask];
  290. NSArray<NSString *> *keys = @[@"FacebookAutoInitEnabled",
  291. @"FacebookAutoLogAppEventsEnabled",
  292. @"FacebookAdvertiserIDCollectionEnabled"];
  293. NSArray<NSNumber *> *defaultValues = @[@YES, @YES, @YES];
  294. NSInteger initialBitmask = 0;
  295. NSInteger usageBitmask = 0;
  296. for (int i = 0; i < keys.count; i++) {
  297. NSNumber *plistValue = [[NSBundle mainBundle] objectForInfoDictionaryKey:keys[i]];
  298. BOOL initialValue = [(plistValue ?: defaultValues[i]) boolValue];
  299. initialBitmask |= (initialValue ? 1 : 0) << i;
  300. usageBitmask |= (plistValue != nil ? 1 : 0) << i;
  301. }
  302. [FBSDKAppEvents logInternalEvent:@"fb_sdk_settings_changed"
  303. parameters:@{@"usage": @(usageBitmask),
  304. @"initial": @(initialBitmask),
  305. @"previous":@(previousBitmask),
  306. @"current": @(bitmask)}
  307. isImplicitlyLogged:YES];
  308. }
  309. }
  310. #pragma mark - Internal - Graph API Debug
  311. + (void)updateGraphAPIDebugBehavior
  312. {
  313. // Enable Warnings everytime Info is enabled
  314. if ([g_loggingBehaviors containsObject:FBSDKLoggingBehaviorGraphAPIDebugInfo]
  315. && ![g_loggingBehaviors containsObject:FBSDKLoggingBehaviorGraphAPIDebugWarning]) {
  316. [g_loggingBehaviors addObject:FBSDKLoggingBehaviorGraphAPIDebugWarning];
  317. }
  318. }
  319. + (NSString *)graphAPIDebugParamValue
  320. {
  321. if ([[self loggingBehaviors] containsObject:FBSDKLoggingBehaviorGraphAPIDebugInfo]) {
  322. return @"info";
  323. } else if ([[self loggingBehaviors] containsObject:FBSDKLoggingBehaviorGraphAPIDebugWarning]) {
  324. return @"warning";
  325. }
  326. return nil;
  327. }
  328. @end