diff --git a/CHANGELOG.md b/CHANGELOG.md index a0e957414..aeff49a2a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -256,9 +256,10 @@ Bugsnag Notifiers on other platforms. should be performed prior to calling `Bugsnag.start()`. * User information is now persisted between application runs by default. When set a users' - email, id and name are set on `BugsnagConfiguration` they are stored in the Keychain and + email, id and name are set on `BugsnagConfiguration` they are stored in the User Defaults and restored if an application is restarted. The values are also copied to the configuration metadata. [#469](https://github.com/bugsnag/bugsnag-cocoa/pull/469) + [#590](https://github.com/bugsnag/bugsnag-cocoa/pull/590) * Added callback-free method to leave breadcrumbs: `[Bugsnag leaveBreadcrumbWithMessage:metadata:andType]` (Swift: `Bugsnag.leaveBreadcrumb(_, metadata:, type:)`) diff --git a/OSX/Bugsnag.xcodeproj/project.pbxproj b/OSX/Bugsnag.xcodeproj/project.pbxproj index 773e3021a..13c10f06a 100644 --- a/OSX/Bugsnag.xcodeproj/project.pbxproj +++ b/OSX/Bugsnag.xcodeproj/project.pbxproj @@ -505,7 +505,6 @@ E7433AD31F4F64F400C082D1 /* libc++.tbd in Frameworks */, E7433AD21F4F64EF00C082D1 /* libz.tbd in Frameworks */, 8A2C8FF01C6BC3A200846019 /* SystemConfiguration.framework in Frameworks */, - 004A41F223FEE08E0092DF97 /* Security.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -520,17 +519,6 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 004A41DD23FEDF2B0092DF97 /* SSKeychain */ = { - isa = PBXGroup; - children = ( - 0061D8392405B23A0041C068 /* BSG_SSKeychain.h */, - 0061D8372405B23A0041C068 /* BSG_SSKeychain.m */, - 0061D8382405B23A0041C068 /* LICENSE */, - ); - name = SSKeychain; - path = ../Source/SSKeychain; - sourceTree = ""; - }; 8A2C8F971C6BC1F700846019 = { isa = PBXGroup; children = ( @@ -590,7 +578,6 @@ 8A2C8FA61C6BC1F700846019 /* Info.plist */, 8A2C902F1C6BF3AC00846019 /* module.modulemap */, E79E6B081F4E3850002B35F9 /* BSG_KSCrash */, - 004A41DD23FEDF2B0092DF97 /* SSKeychain */, ); name = Bugsnag; sourceTree = SOURCE_ROOT; @@ -1043,7 +1030,6 @@ E79E6BC41F4E3850002B35F9 /* BSG_KSMachApple.h in Headers */, 009DF96B2432872D000A8363 /* BugsnagMetadataStore.h in Headers */, E7819BB02459759D00A7EBDD /* BugsnagNotifier.h in Headers */, - 0061D83C2405B23A0041C068 /* BSG_SSKeychain.h in Headers */, E79E6BAD1F4E3850002B35F9 /* BSG_KSCrashSentry_User.h in Headers */, E79E6BA01F4E3850002B35F9 /* BSG_KSCrashSentry.h in Headers */, E79E6BA91F4E3850002B35F9 /* BSG_KSCrashSentry_Private.h in Headers */, @@ -1140,7 +1126,6 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 0061D83B2405B23A0041C068 /* LICENSE in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1227,7 +1212,6 @@ E79148521FD82B36003EFEBF /* BugsnagUser.m in Sources */, E79E6B891F4E3850002B35F9 /* BSG_KSCrash.m in Sources */, E79E6BAC1F4E3850002B35F9 /* BSG_KSCrashSentry_User.c in Sources */, - 0061D83A2405B23A0041C068 /* BSG_SSKeychain.m in Sources */, E79148581FD82B36003EFEBF /* BugsnagFileStore.m in Sources */, E79E6BDA1F4E3850002B35F9 /* BSG_RFC3339DateTool.m in Sources */, E72352C21F55924A00436528 /* BSGConnectivity.m in Sources */, diff --git a/Source/BugsnagConfiguration.m b/Source/BugsnagConfiguration.m index d8e53c750..1c63db47e 100644 --- a/Source/BugsnagConfiguration.m +++ b/Source/BugsnagConfiguration.m @@ -34,7 +34,6 @@ #import "BugsnagSessionTracker.h" #import "BugsnagLogger.h" #import "BSGConfigurationBuilder.h" -#import "BSG_SSKeychain.h" #import "BugsnagBreadcrumbs.h" #import "BugsnagMetadataStore.h" #import "BSGSerialization.h" @@ -52,7 +51,6 @@ static const int BSGApiKeyLength = 32; // User info persistence keys -NSString * const kBugsnagUserKeychainAccount = @"BugsnagUserKeychainAccount"; NSString * const kBugsnagUserEmailAddress = @"BugsnagUserEmailAddress"; NSString * const kBugsnagUserName = @"BugsnagUserName"; NSString * const kBugsnagUserUserId = @"BugsnagUserUserId"; @@ -386,9 +384,10 @@ - (void)setPersistUser:(BOOL)persistUser { */ - (BugsnagUser *)getPersistedUserData { @synchronized(self) { - NSString *email = [BSG_SSKeychain passwordForService:kBugsnagUserEmailAddress account:kBugsnagUserKeychainAccount]; - NSString *name = [BSG_SSKeychain passwordForService:kBugsnagUserName account:kBugsnagUserKeychainAccount]; - NSString *userId = [BSG_SSKeychain passwordForService:kBugsnagUserUserId account:kBugsnagUserKeychainAccount]; + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + NSString *email = [userDefaults objectForKey:kBugsnagUserEmailAddress]; + NSString *name = [userDefaults objectForKey:kBugsnagUserName]; + NSString *userId = [userDefaults objectForKey:kBugsnagUserUserId]; if (email || name || userId) { return [[BugsnagUser alloc] initWithUserId:userId name:name emailAddress:email]; @@ -405,37 +404,30 @@ - (BugsnagUser *)getPersistedUserData { - (void)persistUserData { @synchronized(self) { if (_user) { + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + // Email if (_user.email) { - [BSG_SSKeychain setPassword:_user.email - forService:kBugsnagUserEmailAddress - account:kBugsnagUserKeychainAccount]; + [userDefaults setObject:_user.email forKey:kBugsnagUserEmailAddress]; } else { - [BSG_SSKeychain deletePasswordForService:kBugsnagUserEmailAddress - account:kBugsnagUserKeychainAccount]; + [userDefaults removeObjectForKey:kBugsnagUserEmailAddress]; } // Name if (_user.name) { - [BSG_SSKeychain setPassword:_user.name - forService:kBugsnagUserName - account:kBugsnagUserKeychainAccount]; + [userDefaults setObject:_user.name forKey:kBugsnagUserName]; } else { - [BSG_SSKeychain deletePasswordForService:kBugsnagUserName - account:kBugsnagUserKeychainAccount]; + [userDefaults removeObjectForKey:kBugsnagUserName]; } // UserId if (_user.id) { - [BSG_SSKeychain setPassword:_user.id - forService:kBugsnagUserUserId - account:kBugsnagUserKeychainAccount]; + [userDefaults setObject:_user.id forKey:kBugsnagUserUserId]; } else { - [BSG_SSKeychain deletePasswordForService:kBugsnagUserUserId - account:kBugsnagUserKeychainAccount]; + [userDefaults removeObjectForKey:kBugsnagUserUserId]; } } } @@ -446,9 +438,10 @@ - (void)persistUserData { */ -(void)deletePersistedUserData { @synchronized(self) { - [BSG_SSKeychain deletePasswordForService:kBugsnagUserEmailAddress account:kBugsnagUserKeychainAccount]; - [BSG_SSKeychain deletePasswordForService:kBugsnagUserName account:kBugsnagUserKeychainAccount]; - [BSG_SSKeychain deletePasswordForService:kBugsnagUserUserId account:kBugsnagUserKeychainAccount]; + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + [userDefaults removeObjectForKey:kBugsnagUserEmailAddress]; + [userDefaults removeObjectForKey:kBugsnagUserName]; + [userDefaults removeObjectForKey:kBugsnagUserUserId]; } } diff --git a/Source/SSKeychain/BSG_SSKeychain.h b/Source/SSKeychain/BSG_SSKeychain.h deleted file mode 100644 index 8783e588f..000000000 --- a/Source/SSKeychain/BSG_SSKeychain.h +++ /dev/null @@ -1,353 +0,0 @@ -// -// BSG_SSKeychain.h -// SSToolkit -// -// Created by Sam Soffes on 5/19/10. -// Copyright (c) 2009-2011 Sam Soffes. All rights reserved. -// - -#import -#import - -/** Error codes that can be returned in NSError objects. */ -typedef enum { - /** No error. */ - BSG_SSKeychainErrorNone = noErr, - - /** Some of the arguments were invalid. */ - BSG_SSKeychainErrorBadArguments = -1001, - - /** There was no password. */ - BSG_SSKeychainErrorNoPassword = -1002, - - /** One or more parameters passed internally were not valid. */ - BSG_SSKeychainErrorInvalidParameter = errSecParam, - - /** Failed to allocate memory. */ - BSG_SSKeychainErrorFailedToAllocated = errSecAllocate, - - /** No trust results are available. */ - BSG_SSKeychainErrorNotAvailable = errSecNotAvailable, - - /** Authorization/Authentication failed. */ - BSG_SSKeychainErrorAuthorizationFailed = errSecAuthFailed, - - /** The item already exists. */ - BSG_SSKeychainErrorDuplicatedItem = errSecDuplicateItem, - - /** The item cannot be found.*/ - BSG_SSKeychainErrorNotFound = errSecItemNotFound, - - /** Interaction with the Security Server is not allowed. */ - BSG_SSKeychainErrorInteractionNotAllowed = errSecInteractionNotAllowed, - - /** Unable to decode the provided data. */ - BSG_SSKeychainErrorFailedToDecode = errSecDecode -} BSG_SSKeychainErrorCode; - -extern NSString *const BSG_kSSKeychainErrorDomain; - -/** Account name. */ -extern NSString *const BSG_kSSKeychainAccountKey; - -/** - Time the item was created. - - The value will be a string. - */ -extern NSString *const BSG_kSSKeychainCreatedAtKey; - -/** Item class. */ -extern NSString *const BSG_kSSKeychainClassKey; - -/** Item description. */ -extern NSString *const BSG_kSSKeychainDescriptionKey; - -/** Item label. */ -extern NSString *const BSG_kSSKeychainLabelKey; - -/** Time the item was last modified. - - The value will be a string. - */ -extern NSString *const BSG_kSSKeychainLastModifiedKey; - -/** Where the item was created. */ -extern NSString *const BSG_kSSKeychainWhereKey; - -/** - Simple wrapper for accessing accounts, getting passwords, setting passwords, and deleting passwords using the system - Keychain on Mac OS X and iOS. - - This was originally inspired by EMKeychain and SDKeychain (both of which are now gone). Thanks to the authors. - BSG_SSKeychain has since switched to a simpler implementation that was abstracted from [SSToolkit](http://sstoolk.it). - */ -@interface BSG_SSKeychain : NSObject - -///----------------------- -/// @name Getting Accounts -///----------------------- - -/** - Returns an array containing the Keychain's accounts, or `nil` if the Keychain has no accounts. - - See the `NSString` constants declared in BSG_SSKeychain.h for a list of keys that can be used when accessing the - dictionaries returned by this method. - - @return An array of dictionaries containing the Keychain's accounts, or `nil` if the Keychain doesn't have any - accounts. The order of the objects in the array isn't defined. - - @see allAccounts: - */ -+ (NSArray *)allAccounts; - -/** - Returns an array containing the Keychain's accounts, or `nil` if the Keychain doesn't have any - accounts. - - See the `NSString` constants declared in BSG_SSKeychain.h for a list of keys that can be used when accessing the - dictionaries returned by this method. - - @param error If accessing the accounts fails, upon return contains an error that describes the problem. - - @return An array of dictionaries containing the Keychain's accounts, or `nil` if the Keychain doesn't have any - accounts. The order of the objects in the array isn't defined. - - @see allAccounts - */ -+ (NSArray *)allAccounts:(NSError **)error; - -/** - Returns an array containing the Keychain's accounts for a given service, or `nil` if the Keychain doesn't have any - accounts for the given service. - - See the `NSString` constants declared in BSG_SSKeychain.h for a list of keys that can be used when accessing the - dictionaries returned by this method. - - @param serviceName The service for which to return the corresponding accounts. - - @return An array of dictionaries containing the Keychain's accountsfor a given `serviceName`, or `nil` if the Keychain - doesn't have any accounts for the given `serviceName`. The order of the objects in the array isn't defined. - - @see accountsForService:error: - */ -+ (NSArray *)accountsForService:(NSString *)serviceName; - -/** - Returns an array containing the Keychain's accounts for a given service, or `nil` if the Keychain doesn't have any - accounts for the given service. - - @param serviceName The service for which to return the corresponding accounts. - - @param error If accessing the accounts fails, upon return contains an error that describes the problem. - - @return An array of dictionaries containing the Keychain's accountsfor a given `serviceName`, or `nil` if the Keychain - doesn't have any accounts for the given `serviceName`. The order of the objects in the array isn't defined. - - @see accountsForService: - */ -+ (NSArray *)accountsForService:(NSString *)serviceName error:(NSError **)error; - - -///------------------------ -/// @name Getting Passwords -///------------------------ - -/** - Returns a string containing the password for a given account and service, or `nil` if the Keychain doesn't have a - password for the given parameters. - - @param serviceName The service for which to return the corresponding password. - - @param account The account for which to return the corresponding password. - - @return Returns a string containing the password for a given account and service, or `nil` if the Keychain doesn't - have a password for the given parameters. - - @see passwordForService:account:error: - */ -+ (NSString *)passwordForService:(NSString *)serviceName account:(NSString *)account; - -/** - Returns a string containing the password for a given account and service, or `nil` if the Keychain doesn't have a - password for the given parameters. - - @param serviceName The service for which to return the corresponding password. - - @param account The account for which to return the corresponding password. - - @param error If accessing the password fails, upon return contains an error that describes the problem. - - @return Returns a string containing the password for a given account and service, or `nil` if the Keychain doesn't - have a password for the given parameters. - - @see passwordForService:account: - */ -+ (NSString *)passwordForService:(NSString *)serviceName account:(NSString *)account error:(NSError **)error; - -/** - Returns the password data for a given account and service, or `nil` if the Keychain doesn't have data - for the given parameters. - - @param serviceName The service for which to return the corresponding password. - - @param account The account for which to return the corresponding password. - - @return Returns a the password data for the given account and service, or `nil` if the Keychain doesn't - have data for the given parameters. - - @see passwordDataForService:account:error: - */ -+ (NSData *)passwordDataForService:(NSString *)serviceName account:(NSString *)account; - -/** - Returns the password data for a given account and service, or `nil` if the Keychain doesn't have data - for the given parameters. - - @param serviceName The service for which to return the corresponding password. - - @param account The account for which to return the corresponding password. - - @param error If accessing the password fails, upon return contains an error that describes the problem. - - @return Returns a the password data for the given account and service, or `nil` if the Keychain doesn't - have a password for the given parameters. - - @see passwordDataForService:account: - */ -+ (NSData *)passwordDataForService:(NSString *)serviceName account:(NSString *)account error:(NSError **)error; - - -///------------------------- -/// @name Deleting Passwords -///------------------------- - -/** - Deletes a password from the Keychain. - - @param serviceName The service for which to delete the corresponding password. - - @param account The account for which to delete the corresponding password. - - @return Returns `YES` on success, or `NO` on failure. - - @see deletePasswordForService:account:error: - */ -+ (BOOL)deletePasswordForService:(NSString *)serviceName account:(NSString *)account; - -/** - Deletes a password from the Keychain. - - @param serviceName The service for which to delete the corresponding password. - - @param account The account for which to delete the corresponding password. - - @param error If deleting the password fails, upon return contains an error that describes the problem. - - @return Returns `YES` on success, or `NO` on failure. - - @see deletePasswordForService:account: - */ -+ (BOOL)deletePasswordForService:(NSString *)serviceName account:(NSString *)account error:(NSError **)error; - - -///------------------------ -/// @name Setting Passwords -///------------------------ - -/** - Sets a password in the Keychain. - - @param password The password to store in the Keychain. - - @param serviceName The service for which to set the corresponding password. - - @param account The account for which to set the corresponding password. - - @return Returns `YES` on success, or `NO` on failure. - - @see setPassword:forService:account:error: - */ -+ (BOOL)setPassword:(NSString *)password forService:(NSString *)serviceName account:(NSString *)account; - -/** - Sets a password in the Keychain. - - @param password The password to store in the Keychain. - - @param serviceName The service for which to set the corresponding password. - - @param account The account for which to set the corresponding password. - - @param error If setting the password fails, upon return contains an error that describes the problem. - - @return Returns `YES` on success, or `NO` on failure. - - @see setPassword:forService:account: - */ -+ (BOOL)setPassword:(NSString *)password forService:(NSString *)serviceName account:(NSString *)account error:(NSError **)error; - -/** - Sets arbirary data in the Keychain. - - @param password The data to store in the Keychain. - - @param serviceName The service for which to set the corresponding password. - - @param account The account for which to set the corresponding password. - - @return Returns `YES` on success, or `NO` on failure. - - @see setPasswordData:forService:account:error: - */ -+ (BOOL)setPasswordData:(NSData *)password forService:(NSString *)serviceName account:(NSString *)account; - -/** - Sets arbirary data in the Keychain. - - @param password The data to store in the Keychain. - - @param serviceName The service for which to set the corresponding password. - - @param account The account for which to set the corresponding password. - - @param error If setting the password fails, upon return contains an error that describes the problem. - - @return Returns `YES` on success, or `NO` on failure. - - @see setPasswordData:forService:account: - */ -+ (BOOL)setPasswordData:(NSData *)password forService:(NSString *)serviceName account:(NSString *)account error:(NSError **)error; - - -///-------------------- -/// @name Configuration -///-------------------- - -#if __IPHONE_4_0 && TARGET_OS_IPHONE -/** - Returns the accessibility type for all future passwords saved to the Keychain. - - @return Returns the accessibility type. - - The return value will be `NULL` or one of the "Keychain Item Accessibility Constants" used for determining when a - keychain item should be readable. - - @see accessibilityType - */ -+ (CFTypeRef)accessibilityType; - -/** - Sets the accessibility type for all future passwords saved to the Keychain. - - @param accessibilityType One of the "Keychain Item Accessibility Constants" used for determining when a keychain item - should be readable. - - If the value is `NULL` (the default), the Keychain default will be used. - - @see accessibilityType - */ -+ (void)setAccessibilityType:(CFTypeRef)accessibilityType; -#endif - -@end diff --git a/Source/SSKeychain/BSG_SSKeychain.m b/Source/SSKeychain/BSG_SSKeychain.m deleted file mode 100644 index 4dbd64294..000000000 --- a/Source/SSKeychain/BSG_SSKeychain.m +++ /dev/null @@ -1,268 +0,0 @@ -// -// BSG_SSKeychain.m -// SSToolkit -// -// Created by Sam Soffes on 5/19/10. -// Copyright (c) 2009-2011 Sam Soffes. All rights reserved. -// - -#import "BSG_SSKeychain.h" - -NSString *const BSG_kSSKeychainErrorDomain = @"com.samsoffes.sskeychain"; - -NSString *const BSG_kSSKeychainAccountKey = @"acct"; -NSString *const BSG_kSSKeychainCreatedAtKey = @"cdat"; -NSString *const BSG_kSSKeychainClassKey = @"labl"; -NSString *const BSG_kSSKeychainDescriptionKey = @"desc"; -NSString *const BSG_kSSKeychainLabelKey = @"labl"; -NSString *const BSG_kSSKeychainLastModifiedKey = @"mdat"; -NSString *const BSG_kSSKeychainWhereKey = @"svce"; - -#if __IPHONE_4_0 && TARGET_OS_IPHONE -CFTypeRef BSG_SSKeychainAccessibilityType = NULL; -#endif - -@interface BSG_SSKeychain () -+ (NSMutableDictionary *)_queryForService:(NSString *)service account:(NSString *)account; -@end - -@implementation BSG_SSKeychain - -#pragma mark - Getting Accounts - -+ (NSArray *)allAccounts { - return [self accountsForService:nil error:nil]; -} - - -+ (NSArray *)allAccounts:(NSError **)error { - return [self accountsForService:nil error:error]; -} - - -+ (NSArray *)accountsForService:(NSString *)service { - return [self accountsForService:service error:nil]; -} - - -+ (NSArray *)accountsForService:(NSString *)service error:(NSError **)error { - OSStatus status = BSG_SSKeychainErrorBadArguments; - NSMutableDictionary *query = [self _queryForService:service account:nil]; -#if __has_feature(objc_arc) - [query setObject:(__bridge id)kCFBooleanTrue forKey:(__bridge id)kSecReturnAttributes]; - [query setObject:(__bridge id)kSecMatchLimitAll forKey:(__bridge id)kSecMatchLimit]; -#else - [query setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnAttributes]; - [query setObject:(id)kSecMatchLimitAll forKey:(id)kSecMatchLimit]; -#endif - - CFTypeRef result = NULL; -#if __has_feature(objc_arc) - status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &result); -#else - status = SecItemCopyMatching((CFDictionaryRef)query, &result); -#endif - if (status != noErr && error != NULL) { - *error = [NSError errorWithDomain:BSG_kSSKeychainErrorDomain code:status userInfo:nil]; - return nil; - } - -#if __has_feature(objc_arc) - return (__bridge_transfer NSArray *)result; -#else - return [(NSArray *)result autorelease]; -#endif -} - - -#pragma mark - Getting Passwords - -+ (NSString *)passwordForService:(NSString *)service account:(NSString *)account { - return [self passwordForService:service account:account error:nil]; -} - - -+ (NSString *)passwordForService:(NSString *)service account:(NSString *)account error:(NSError **)error { - NSData *data = [self passwordDataForService:service account:account error:error]; - if (data.length > 0) { - NSString *string = [[NSString alloc] initWithData:(NSData *)data encoding:NSUTF8StringEncoding]; -#if !__has_feature(objc_arc) - [string autorelease]; -#endif - return string; - } - - return nil; -} - - -+ (NSData *)passwordDataForService:(NSString *)service account:(NSString *)account { - return [self passwordDataForService:service account:account error:nil]; -} - - -+ (NSData *)passwordDataForService:(NSString *)service account:(NSString *)account error:(NSError **)error { - OSStatus status = BSG_SSKeychainErrorBadArguments; - if (!service || !account) { - if (error) { - *error = [NSError errorWithDomain:BSG_kSSKeychainErrorDomain code:status userInfo:nil]; - } - return nil; - } - - CFTypeRef result = NULL; - NSMutableDictionary *query = [self _queryForService:service account:account]; -#if __has_feature(objc_arc) - [query setObject:(__bridge id)kCFBooleanTrue forKey:(__bridge id)kSecReturnData]; - [query setObject:(__bridge id)kSecMatchLimitOne forKey:(__bridge id)kSecMatchLimit]; - status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &result); -#else - [query setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData]; - [query setObject:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit]; - status = SecItemCopyMatching((CFDictionaryRef)query, &result); -#endif - - if (status != noErr && error != NULL) { - *error = [NSError errorWithDomain:BSG_kSSKeychainErrorDomain code:status userInfo:nil]; - return nil; - } - -#if __has_feature(objc_arc) - return (__bridge_transfer NSData *)result; -#else - return [(NSData *)result autorelease]; -#endif -} - - -#pragma mark - Deleting Passwords - -+ (BOOL)deletePasswordForService:(NSString *)service account:(NSString *)account { - return [self deletePasswordForService:service account:account error:nil]; -} - - -+ (BOOL)deletePasswordForService:(NSString *)service account:(NSString *)account error:(NSError **)error { - OSStatus status = BSG_SSKeychainErrorBadArguments; - if (service && account) { - NSMutableDictionary *query = [self _queryForService:service account:account]; -#if __has_feature(objc_arc) - status = SecItemDelete((__bridge CFDictionaryRef)query); -#else - status = SecItemDelete((CFDictionaryRef)query); -#endif - } - if (status != noErr && error != NULL) { - *error = [NSError errorWithDomain:BSG_kSSKeychainErrorDomain code:status userInfo:nil]; - } - return (status == noErr); - -} - - -#pragma mark - Setting Passwords - -+ (BOOL)setPassword:(NSString *)password forService:(NSString *)service account:(NSString *)account { - return [self setPassword:password forService:service account:account error:nil]; -} - - -+ (BOOL)setPassword:(NSString *)password forService:(NSString *)service account:(NSString *)account error:(NSError **)error { - NSData *data = [password dataUsingEncoding:NSUTF8StringEncoding]; - return [self setPasswordData:data forService:service account:account error:error]; -} - - -+ (BOOL)setPasswordData:(NSData *)password forService:(NSString *)service account:(NSString *)account { - return [self setPasswordData:password forService:service account:account error:nil]; -} - - -+ (BOOL)setPasswordData:(NSData *)password forService:(NSString *)service account:(NSString *)account error:(NSError **)error { - OSStatus status = BSG_SSKeychainErrorBadArguments; - if (password && service && account) { - [self deletePasswordForService:service account:account]; - NSMutableDictionary *query = [self _queryForService:service account:account]; -#if __has_feature(objc_arc) - [query setObject:password forKey:(__bridge id)kSecValueData]; -#else - [query setObject:password forKey:(id)kSecValueData]; -#endif - -#if __IPHONE_4_0 && TARGET_OS_IPHONE - if (BSG_SSKeychainAccessibilityType) { -#if __has_feature(objc_arc) - [query setObject:(id)[self accessibilityType] forKey:(__bridge id)kSecAttrAccessible]; -#else - [query setObject:(id)[self accessibilityType] forKey:(id)kSecAttrAccessible]; -#endif - } -#endif - -#if __has_feature(objc_arc) -// CFTypeRef _Nullable *result = NULL; - - - status = SecItemAdd((__bridge CFDictionaryRef)query, NULL); - -// NSLog("%@", (NSDictionary *)result); - -#else - status = SecItemAdd((CFDictionaryRef)query, NULL); -#endif - } - if (status != noErr && error != NULL) { - *error = [NSError errorWithDomain:BSG_kSSKeychainErrorDomain code:status userInfo:nil]; - } - return (status == noErr); -} - - -#pragma mark - Configuration - -#if __IPHONE_4_0 && TARGET_OS_IPHONE -+ (CFTypeRef)accessibilityType { - return BSG_SSKeychainAccessibilityType; -} - - -+ (void)setAccessibilityType:(CFTypeRef)accessibilityType { - CFRetain(accessibilityType); - if (BSG_SSKeychainAccessibilityType) { - CFRelease(BSG_SSKeychainAccessibilityType); - } - BSG_SSKeychainAccessibilityType = accessibilityType; -} -#endif - - -#pragma mark - Private - -+ (NSMutableDictionary *)_queryForService:(NSString *)service account:(NSString *)account { - NSMutableDictionary *dictionary = [NSMutableDictionary dictionaryWithCapacity:3]; -#if __has_feature(objc_arc) - [dictionary setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass]; -#else - [dictionary setObject:(id)kSecClassGenericPassword forKey:(id)kSecClass]; -#endif - - if (service) { -#if __has_feature(objc_arc) - [dictionary setObject:service forKey:(__bridge id)kSecAttrService]; -#else - [dictionary setObject:service forKey:(id)kSecAttrService]; -#endif - } - - if (account) { -#if __has_feature(objc_arc) - [dictionary setObject:account forKey:(__bridge id)kSecAttrAccount]; -#else - [dictionary setObject:account forKey:(id)kSecAttrAccount]; -#endif - } - - return dictionary; -} - -@end diff --git a/Source/SSKeychain/LICENSE b/Source/SSKeychain/LICENSE deleted file mode 100644 index b63e07723..000000000 --- a/Source/SSKeychain/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -Copyright (c) 2010-2012 Sam Soffes. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/Tests/BugsnagConfigurationTests.m b/Tests/BugsnagConfigurationTests.m index e8fae6105..a915b2490 100644 --- a/Tests/BugsnagConfigurationTests.m +++ b/Tests/BugsnagConfigurationTests.m @@ -12,7 +12,6 @@ #import "BugsnagSessionTracker.h" #import "BugsnagUser.h" #import "BSG_KSCrashType.h" -#import "BSG_SSKeychain.h" // ============================================================================= // MARK: - Required private methods @@ -369,25 +368,21 @@ - (void)testSetMalformedNotifyEndpoint { // ============================================================================= // MARK: - User persistence tests // ============================================================================= -/** - * We'd like to test user persistence here but we're not able to. Keychain access requires correct - * entitlements, and these can only be associated with an application, not a framework. Creating a - * dummy app and associating it with the test target is possible but raises issues around signing - * as well as breaking preexisting tests. - * - * See e.g. https://forums.developer.apple.com/thread/60617 for some background. - * also: https://forums.developer.apple.com/message/179846 - * and: https://github.com/samsoffes/sskeychain - * - * The solution is to shift the testing of the user persistence feature to the end-to-end integration - * tests, located in /features/user_persistence.feature. These do have an associated test app, - * but require the bugsnag-mazerunner project (available on github) to run locally. - * - * For the purposes of contributing to coverage and in case the Entitlement situation is mitigated in the - * future the tests are left in place, but have had failing assertions commented out. - */ + +NSString * const kBugsnagUserEmailAddress = @"BugsnagUserEmailAddress"; +NSString * const kBugsnagUserName = @"BugsnagUserName"; +NSString * const kBugsnagUserUserId = @"BugsnagUserUserId"; + +// Helper +- (void)getName:(NSString **)name email:(NSString **)email id:(NSString ** )id { + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + *email = [userDefaults objectForKey:kBugsnagUserEmailAddress]; + *id = [userDefaults objectForKey:kBugsnagUserUserId]; + *name = [userDefaults objectForKey:kBugsnagUserName]; +} - (void)testUserPersistence { + NSString *userDefaultEmail, *userDefaultName, *userDefaultUserId; NSString *email = @"test@example.com"; NSString *name = @"foo"; NSString *userId = @"123"; @@ -399,44 +394,50 @@ - (void)testUserPersistence { // Start with no persisted user data [config deletePersistedUserData]; -// XCTAssertNil([bsg_SSKeychain passwordForService:kBugsnagUserEmailAddress account:kBugsnagUserKeychainAccount]); -// XCTAssertNil([bsg_SSKeychain passwordForService:kBugsnagUserName account:kBugsnagUserKeychainAccount]); -// XCTAssertNil([bsg_SSKeychain passwordForService:kBugsnagUserUserId account:kBugsnagUserKeychainAccount]); + [self getName:&userDefaultName email:&userDefaultEmail id:&userDefaultUserId]; + XCTAssertNil(userDefaultEmail); + XCTAssertNil(userDefaultName); + XCTAssertNil(userDefaultUserId); // user should be persisted by default [config setUser:userId withEmail:email andName:name]; // Check values manually -// XCTAssertEqualObjects([bsg_SSKeychain passwordForService:kBugsnagUserEmailAddress account:kBugsnagUserKeychainAccount], email); -// XCTAssertEqualObjects([bsg_SSKeychain passwordForService:kBugsnagUserName account:kBugsnagUserKeychainAccount], name); -// XCTAssertEqualObjects([bsg_SSKeychain passwordForService:kBugsnagUserUserId account:kBugsnagUserKeychainAccount], userId); + [self getName:&userDefaultName email:&userDefaultEmail id:&userDefaultUserId]; + XCTAssertEqualObjects(userDefaultEmail, email); + XCTAssertEqualObjects(userDefaultName, name); + XCTAssertEqualObjects(userDefaultUserId, userId); // Check persistence between invocations (when values have been set) BugsnagConfiguration *config2 = [[BugsnagConfiguration alloc] initWithApiKey:DUMMY_APIKEY_32CHAR_1]; - -// XCTAssertEqualObjects(config2.currentUser.emailAddress, email); -// XCTAssertTrue([config2.currentUser.name isEqualToString:name]); -// XCTAssertTrue([config2.currentUser.userId isEqualToString:userId]); + XCTAssertEqualObjects(config2.user.email, email); + XCTAssertEqualObjects(config2.user.name, name); + XCTAssertEqualObjects(config2.user.id, userId); // Check that values we know to have been persisted are actuallty deleted. [config2 deletePersistedUserData]; -// XCTAssertNil([bsg_SSKeychain passwordForService:kBugsnagUserEmailAddress account:kBugsnagUserKeychainAccount]); -// XCTAssertNil([bsg_SSKeychain passwordForService:kBugsnagUserName account:kBugsnagUserKeychainAccount]); -// XCTAssertNil([bsg_SSKeychain passwordForService:kBugsnagUserUserId account:kBugsnagUserKeychainAccount]); + [self getName:&userDefaultName email:&userDefaultEmail id:&userDefaultUserId]; + XCTAssertNil(userDefaultEmail); + XCTAssertNil(userDefaultName); + XCTAssertNil(userDefaultUserId); } /** * Test that user data is (as far as we can tell) not persisted */ - (void)testUserNonPesistence { + NSString *userDefaultEmail, *userDefaultName, *userDefaultUserId; + BugsnagConfiguration *config = [[BugsnagConfiguration alloc] initWithApiKey:DUMMY_APIKEY_32CHAR_1]; config.persistUser = false; [config deletePersistedUserData]; // Should be no persisted data, and should not persist between invocations -// XCTAssertNil([bsg_SSKeychain passwordForService:kBugsnagUserEmailAddress account:kBugsnagUserKeychainAccount]); -// XCTAssertNil([bsg_SSKeychain passwordForService:kBugsnagUserName account:kBugsnagUserKeychainAccount]); -// XCTAssertNil([bsg_SSKeychain passwordForService:kBugsnagUserUserId account:kBugsnagUserKeychainAccount]); + [config deletePersistedUserData]; + [self getName:&userDefaultName email:&userDefaultEmail id:&userDefaultUserId]; + XCTAssertNil(userDefaultEmail); + XCTAssertNil(userDefaultName); + XCTAssertNil(userDefaultUserId); BugsnagConfiguration *config2 = [[BugsnagConfiguration alloc] initWithApiKey:DUMMY_APIKEY_32CHAR_1]; XCTAssertNotNil(config2.user); @@ -448,39 +449,51 @@ - (void)testUserNonPesistence { /** * Test partial parsistence */ + - (void)testPartialPesistence { + NSString *userDefaultEmail, *userDefaultName, *userDefaultUserId; + [self getName:&userDefaultName email:&userDefaultEmail id:&userDefaultUserId]; + NSString *email = @"test@example.com"; NSString *name = @"foo"; NSString *userId = @"123"; - + BugsnagConfiguration *config = [[BugsnagConfiguration alloc] initWithApiKey:DUMMY_APIKEY_32CHAR_1]; XCTAssertTrue(config.persistUser); [config deletePersistedUserData]; // Should be no persisted data -// XCTAssertNil([bsg_SSKeychain passwordForService:kBugsnagUserEmailAddress account:kBugsnagUserKeychainAccount]); -// XCTAssertNil([bsg_SSKeychain passwordForService:kBugsnagUserName account:kBugsnagUserKeychainAccount]); -// XCTAssertNil([bsg_SSKeychain passwordForService:kBugsnagUserUserId account:kBugsnagUserKeychainAccount]); - + [config deletePersistedUserData]; + [self getName:&userDefaultName email:&userDefaultEmail id:&userDefaultUserId]; + XCTAssertNil(userDefaultEmail); + XCTAssertNil(userDefaultName); + XCTAssertNil(userDefaultUserId); + [config setUser:userId withEmail:nil andName:nil]; -// XCTAssertNil([bsg_SSKeychain passwordForService:kBugsnagUserEmailAddress account:kBugsnagUserKeychainAccount]); -// XCTAssertNil([bsg_SSKeychain passwordForService:kBugsnagUserName account:kBugsnagUserKeychainAccount]); -// XCTAssertEqualObjects([bsg_SSKeychain passwordForService:kBugsnagUserUserId account:kBugsnagUserKeychainAccount], userId); + [self getName:&userDefaultName email:&userDefaultEmail id:&userDefaultUserId]; + XCTAssertNil(userDefaultEmail); + XCTAssertNil(userDefaultName); + XCTAssertEqualObjects(userDefaultUserId, userId); + [config setUser:nil withEmail:email andName:nil]; -// XCTAssertNil([bsg_SSKeychain passwordForService:kBugsnagUserEmailAddress account:kBugsnagUserKeychainAccount]); -// XCTAssertEqualObjects([bsg_SSKeychain passwordForService:kBugsnagUserName account:kBugsnagUserKeychainAccount], name); -// XCTAssertNil([bsg_SSKeychain passwordForService:kBugsnagUserUserId account:kBugsnagUserKeychainAccount]); + [self getName:&userDefaultName email:&userDefaultEmail id:&userDefaultUserId]; + XCTAssertNil(userDefaultName); + XCTAssertEqualObjects(userDefaultEmail, email); + XCTAssertNil(userDefaultUserId); [config setUser:nil withEmail:nil andName:name]; -// XCTAssertEqualObjects([bsg_SSKeychain passwordForService:kBugsnagUserEmailAddress account:kBugsnagUserKeychainAccount], email); -// XCTAssertNil([bsg_SSKeychain passwordForService:kBugsnagUserName account:kBugsnagUserKeychainAccount]); -// XCTAssertNil([bsg_SSKeychain passwordForService:kBugsnagUserUserId account:kBugsnagUserKeychainAccount]); + [self getName:&userDefaultName email:&userDefaultEmail id:&userDefaultUserId]; + XCTAssertEqualObjects(userDefaultName, name); + XCTAssertNil(userDefaultEmail); + XCTAssertNil(userDefaultUserId); } /** * Test that persisting a BugsnagUser with all nil fields behaves as expected */ - (void)testAllUserDataNilPersistence { + NSString *userDefaultEmail, *userDefaultName, *userDefaultUserId; + BugsnagConfiguration *config = [[BugsnagConfiguration alloc] initWithApiKey:DUMMY_APIKEY_32CHAR_1]; XCTAssertTrue(config.persistUser); [config deletePersistedUserData]; @@ -491,15 +504,17 @@ - (void)testAllUserDataNilPersistence { XCTAssertNotNil(config.user); // But there hould be no persisted data -// XCTAssertNil([bsg_SSKeychain passwordForService:kBugsnagUserEmailAddress account:kBugsnagUserKeychainAccount]); -// XCTAssertNil([bsg_SSKeychain passwordForService:kBugsnagUserName account:kBugsnagUserKeychainAccount]); -// XCTAssertNil([bsg_SSKeychain passwordForService:kBugsnagUserUserId account:kBugsnagUserKeychainAccount]); + [self getName:&userDefaultName email:&userDefaultEmail id:&userDefaultUserId]; + XCTAssertNil(userDefaultName); + XCTAssertNil(userDefaultEmail); + XCTAssertNil(userDefaultUserId); } /** * Test that the configuration metadata is set correctly. */ - (void)testUserPersistenceAndMetadata { + NSString *userDefaultEmail, *userDefaultName, *userDefaultUserId; NSString *email = @"test@example.com"; NSString *name = @"foo"; NSString *userId = @"123"; @@ -509,48 +524,24 @@ - (void)testUserPersistenceAndMetadata { [config deletePersistedUserData]; // Should be no persisted data -// XCTAssertNil([bsg_SSKeychain passwordForService:kBugsnagUserEmailAddress account:kBugsnagUserKeychainAccount]); -// XCTAssertNil([bsg_SSKeychain passwordForService:kBugsnagUserName account:kBugsnagUserKeychainAccount]); -// XCTAssertNil([bsg_SSKeychain passwordForService:kBugsnagUserUserId account:kBugsnagUserKeychainAccount]); + [self getName:&userDefaultName email:&userDefaultEmail id:&userDefaultUserId]; + XCTAssertNil(userDefaultName); + XCTAssertNil(userDefaultEmail); + XCTAssertNil(userDefaultUserId); // Persist user data [config setUser:userId withEmail:email andName:name]; // Check that retrieving persisted user data also sets configuration metadata // Check persistence between invocations (when values have been set) -// BugsnagConfiguration *config2 = [[BugsnagConfiguration alloc] initWithApiKey:DUMMY_APIKEY_32CHAR_1]; -// XCTAssertTrue([config2.currentUser.emailAddress isEqualToString:email]); -// XCTAssertTrue([config2.currentUser.name isEqualToString:name]); -// XCTAssertTrue([config2.currentUser.userId isEqualToString:userId]); - -// XCTAssertEqualObjects([config2.metadata getMetadata:BSGKeyUser key:BSGKeyEmail], email); -// XCTAssertEqualObjects([config2.metadata getMetadata:BSGKeyUser key:BSGKeyName], name); -// XCTAssertEqualObjects([config2.metadata getMetadata:BSGKeyUser key:BSGKeyId], userId); -} - -/** - * Test that non-persisted user data interacts correctly with the configuration metadata - */ -- (void)testNonPersistenceAndMetadata { - - NSString *email = @"test@example.com"; - NSString *name = @"foo"; - NSString *userId = @"123"; - - BugsnagConfiguration *config = [[BugsnagConfiguration alloc] initWithApiKey:DUMMY_APIKEY_32CHAR_1]; - XCTAssertTrue(config.persistUser); - [config setPersistUser:false]; - [config deletePersistedUserData]; - BugsnagConfiguration *config2 = [[BugsnagConfiguration alloc] initWithApiKey:DUMMY_APIKEY_32CHAR_1]; -// XCTAssertNil([[config2 metadata] getMetadata:BSGKeyUser key:BSGKeyId]); -// XCTAssertNil([[config2 metadata] getMetadata:BSGKeyUser key:BSGKeyName]); -// XCTAssertNil([[config2 metadata] getMetadata:BSGKeyUser key:BSGKeyEmail]); - - [config2 setUser:userId withEmail:email andName:name]; -// XCTAssertEqualObjects([config2.metadata getMetadata:BSGKeyUser key:BSGKeyEmail], email); -// XCTAssertEqualObjects([config2.metadata getMetadata:BSGKeyUser key:BSGKeyName], name); -// XCTAssertEqualObjects([config2.metadata getMetadata:BSGKeyUser key:BSGKeyId], userId); + XCTAssertEqualObjects(config2.user.email, email); + XCTAssertEqualObjects(config2.user.name, name); + XCTAssertEqualObjects(config2.user.id, userId); + + XCTAssertEqualObjects(config2. user.email, email); + XCTAssertEqualObjects(config2.user.name, name); + XCTAssertEqualObjects(config2.user.id, userId); } - (void)testSettingPersistUser { diff --git a/iOS/Bugsnag.xcodeproj/project.pbxproj b/iOS/Bugsnag.xcodeproj/project.pbxproj index c327166f4..d9a4d28d5 100644 --- a/iOS/Bugsnag.xcodeproj/project.pbxproj +++ b/iOS/Bugsnag.xcodeproj/project.pbxproj @@ -794,7 +794,6 @@ E7433AD01F4F64D400C082D1 /* libc++.tbd in Frameworks */, E7EC041A1F4CC97200C2E9D5 /* Foundation.framework in Frameworks */, 8A2C8F6C1C6BBE9500846019 /* SystemConfiguration.framework in Frameworks */, - 004A41CE23FE91070092DF97 /* Security.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -829,17 +828,6 @@ path = "Swift Tests"; sourceTree = ""; }; - 0061D84324067AF70041C068 /* SSKeychain */ = { - isa = PBXGroup; - children = ( - 0061D84424067AF70041C068 /* LICENSE */, - 0061D84524067AF70041C068 /* BSG_SSKeychain.m */, - 0061D84624067AF80041C068 /* BSG_SSKeychain.h */, - ); - name = SSKeychain; - path = ../Source/SSKeychain; - sourceTree = ""; - }; 8A2C8F0E1C6BBD2300846019 = { isa = PBXGroup; children = ( @@ -914,7 +902,6 @@ E7529F87243C8DA2006B4932 /* RegisterErrorData.h */, E7529F88243C8DA2006B4932 /* RegisterErrorData.m */, 8A2C8F1D1C6BBD2300846019 /* Info.plist */, - 0061D84324067AF70041C068 /* SSKeychain */, E7107BB31F4C97F100BB3F98 /* KSCrash */, 8A2C8F321C6BBD7200846019 /* module.modulemap */, ); @@ -1357,7 +1344,6 @@ E7107C581F4C97F100BB3F98 /* BSG_KSCrashSentry_User.h in Headers */, E7107C4B1F4C97F100BB3F98 /* BSG_KSCrashSentry.h in Headers */, E7107C541F4C97F100BB3F98 /* BSG_KSCrashSentry_Private.h in Headers */, - 0061D84B24067AF80041C068 /* BSG_SSKeychain.h in Headers */, E737DEA21F73AD7400BC7C80 /* BugsnagHandledState.h in Headers */, E7107C351F4C97F100BB3F98 /* BSG_KSCrashAdvanced.h in Headers */, E7107C711F4C97F100BB3F98 /* BSG_KSObjC.h in Headers */, @@ -1485,7 +1471,6 @@ 000E6EA323D8AC8C009D8194 /* UPGRADING.md in Resources */, E74D8E93243B3DF000F2A630 /* ORGANIZATION.md in Resources */, 000E6EA623D8AC8C009D8194 /* CHANGELOG.md in Resources */, - 0061D84724067AF80041C068 /* LICENSE in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1502,7 +1487,6 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 0061D84824067AF80041C068 /* LICENSE in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1580,7 +1564,6 @@ E7107C851F4C97F100BB3F98 /* BSG_RFC3339DateTool.m in Sources */, F42953297D561ACAB878DEB8 /* BugsnagFileStore.m in Sources */, E790C44F24349898006FFB26 /* BugsnagError.m in Sources */, - 0061D84924067AF80041C068 /* BSG_SSKeychain.m in Sources */, F4295B2AC95281CBA3A42DCA /* BugsnagSessionFileStore.m in Sources */, F4295C52A30DC98515F2FF02 /* BugsnagSessionTrackingApiClient.m in Sources */, F4295168CDC7A77A832C9475 /* BugsnagApiClient.m in Sources */, @@ -1695,7 +1678,6 @@ E7397E421F83BC320034242A /* BSG_KSMach_x86_64.c in Sources */, E7397E431F83BC320034242A /* BSG_KSObjC.c in Sources */, E790C455243498BB006FFB26 /* BugsnagStackframe.m in Sources */, - 0061D84A24067AF80041C068 /* BSG_SSKeychain.m in Sources */, E7397E441F83BC320034242A /* BSG_KSSignalInfo.c in Sources */, E7397E451F83BC320034242A /* BSG_KSString.c in Sources */, E7397E461F83BC320034242A /* BSG_KSSysCtl.c in Sources */, diff --git a/tvOS/Bugsnag.xcodeproj/project.pbxproj b/tvOS/Bugsnag.xcodeproj/project.pbxproj index 9d622baf6..9eec5a457 100644 --- a/tvOS/Bugsnag.xcodeproj/project.pbxproj +++ b/tvOS/Bugsnag.xcodeproj/project.pbxproj @@ -7,10 +7,6 @@ objects = { /* Begin PBXBuildFile section */ - 004A41F023FEE0610092DF97 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 004A41EF23FEE0610092DF97 /* Security.framework */; }; - 0061D8402405B6370041C068 /* BSG_SSKeychain.h in Headers */ = {isa = PBXBuildFile; fileRef = 0061D83D2405B6370041C068 /* BSG_SSKeychain.h */; }; - 0061D8412405B6370041C068 /* BSG_SSKeychain.m in Sources */ = {isa = PBXBuildFile; fileRef = 0061D83E2405B6370041C068 /* BSG_SSKeychain.m */; }; - 0061D8422405B6370041C068 /* LICENSE in Resources */ = {isa = PBXBuildFile; fileRef = 0061D83F2405B6370041C068 /* LICENSE */; }; 0089B6EF241168CC00D5A7F2 /* BugsnagClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 0089B6ED241168CB00D5A7F2 /* BugsnagClient.h */; settings = {ATTRIBUTES = (Public, ); }; }; 0089B6F0241168CC00D5A7F2 /* BugsnagClient.m in Sources */ = {isa = PBXBuildFile; fileRef = 0089B6EE241168CB00D5A7F2 /* BugsnagClient.m */; }; 009DF96D2432876C000A8363 /* BugsnagMetadataStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 009DF96C2432876C000A8363 /* BugsnagMetadataStore.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -253,9 +249,6 @@ /* Begin PBXFileReference section */ 004A41EF23FEE0610092DF97 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; }; - 0061D83D2405B6370041C068 /* BSG_SSKeychain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BSG_SSKeychain.h; sourceTree = ""; }; - 0061D83E2405B6370041C068 /* BSG_SSKeychain.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BSG_SSKeychain.m; sourceTree = ""; }; - 0061D83F2405B6370041C068 /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE; sourceTree = ""; }; 0089B6ED241168CB00D5A7F2 /* BugsnagClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BugsnagClient.h; path = ../Source/BugsnagClient.h; sourceTree = ""; }; 0089B6EE241168CB00D5A7F2 /* BugsnagClient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BugsnagClient.m; path = ../Source/BugsnagClient.m; sourceTree = ""; }; 009DF96C2432876C000A8363 /* BugsnagMetadataStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BugsnagMetadataStore.h; path = ../Source/BugsnagMetadataStore.h; sourceTree = ""; }; @@ -504,7 +497,6 @@ E7433AD81F4F651200C082D1 /* libz.tbd in Frameworks */, E7433AD61F4F650C00C082D1 /* libc++.tbd in Frameworks */, E72352BA1F55922F00436528 /* SystemConfiguration.framework in Frameworks */, - 004A41F023FEE0610092DF97 /* Security.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -519,17 +511,6 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 004A41E623FEDF9E0092DF97 /* SSKeychain */ = { - isa = PBXGroup; - children = ( - 0061D83D2405B6370041C068 /* BSG_SSKeychain.h */, - 0061D83E2405B6370041C068 /* BSG_SSKeychain.m */, - 0061D83F2405B6370041C068 /* LICENSE */, - ); - name = SSKeychain; - path = ../Source/SSKeychain; - sourceTree = ""; - }; 8A8D511A1D41343500D33797 = { isa = PBXGroup; children = ( @@ -590,7 +571,6 @@ E7D2E679243B8FD2005A3041 /* BugsnagStacktrace.h */, E7D2E67A243B8FD2005A3041 /* BugsnagStacktrace.m */, 8A8D51291D41343500D33797 /* Info.plist */, - 004A41E623FEDF9E0092DF97 /* SSKeychain */, E76616FD1F4E459C0094CECF /* BSG_KSCrash */, ); name = tvOS; @@ -1042,7 +1022,6 @@ E76617B91F4E459C0094CECF /* BSG_KSMachApple.h in Headers */, 009DF96D2432876C000A8363 /* BugsnagMetadataStore.h in Headers */, E7819BB5245975BF00A7EBDD /* BugsnagNotifier.h in Headers */, - 0061D8402405B6370041C068 /* BSG_SSKeychain.h in Headers */, E76617A21F4E459C0094CECF /* BSG_KSCrashSentry_User.h in Headers */, E76617951F4E459C0094CECF /* BSG_KSCrashSentry.h in Headers */, E766179E1F4E459C0094CECF /* BSG_KSCrashSentry_Private.h in Headers */, @@ -1139,7 +1118,6 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 0061D8422405B6370041C068 /* LICENSE in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1226,7 +1204,6 @@ 8AD9A4FD1D42EE99004E1CC5 /* Bugsnag.m in Sources */, E766177E1F4E459C0094CECF /* BSG_KSCrash.m in Sources */, E790C49524349D35006FFB26 /* BugsnagError.m in Sources */, - 0061D8412405B6370041C068 /* BSG_SSKeychain.m in Sources */, E76617A11F4E459C0094CECF /* BSG_KSCrashSentry_User.c in Sources */, E76617CF1F4E459C0094CECF /* BSG_RFC3339DateTool.m in Sources */, E72352BE1F55923700436528 /* BSGConnectivity.m in Sources */,