[英]How can I detect if an iOS app is a new install or had been installed and deleted previously
如何检测是首次安装iOS应用还是已删除并重新安装iOS应用?
我在应用程序运行时确实使用NSUserDefaults
。 但是,删除该应用程序后,我相信所有关联数据都将被删除。
我的目标是仅在设备上首次安装该应用程序时才对用户电话号码进行SMS验证。
如果由于某种原因,该应用程序被删除并重新安装,我想避免重做SMS验证。
我还可以做些什么? 是否可以存储与我的应用程序相关的一些元数据,当在设备上删除应用程序本身时,这些元数据不会被删除?
有遵循的标准模式吗?
您可以通过在用户的钥匙串中存储一个值来实现。 即使该应用程序被删除,它也将持续存在,因此您可以确定该应用程序是新安装还是重新安装。 如果两个值都存在,则向用户默认值添加另一个值以进行比较,如果该应用已安装并执行了至少一次。 如果两个值都不存在,则为新的首次安装。 如果仅存在钥匙串值,则可以重新安装。
您可以使用钥匙串,并且在我们卸载应用程序后,钥匙串会存储值。
苹果在其GenericKeyChain中提供了KeyChainItemWrapper类( 示例代码 )
尝试使用以下代码将设备代码存储在钥匙串中.....,即使删除了应用程序,钥匙串值也保持不变:
static NSString *serviceName = @"com.mycompany.myAppServiceName";
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSData *passwordData = [self searchKeychainCopyMatching:@"device--code"];
if (passwordData) {
NSString *password = [[NSString alloc] initWithData:passwordData
encoding:NSUTF8StringEncoding];
NSLog(@"pasword:=%@",password);
}
else{
[self createKeychainValue:devicecode forIdentifier:@"device--code"];
}
//[self deleteKeychainValue:@"device--code"];
return YES;
}
- (void)deleteKeychainValue:(NSString *)identifier {
NSMutableDictionary *searchDictionary = [self newSearchDictionary:identifier];
SecItemDelete((CFDictionaryRef)searchDictionary);
}
- (NSMutableDictionary *)newSearchDictionary:(NSString *)identifier {
NSMutableDictionary *searchDictionary = [[NSMutableDictionary alloc] init];
[searchDictionary setObject:(id)kSecClassGenericPassword forKey:(id)kSecClass];
NSData *encodedIdentifier = [identifier dataUsingEncoding:NSUTF8StringEncoding];
[searchDictionary setObject:encodedIdentifier forKey:(id)kSecAttrGeneric];
[searchDictionary setObject:encodedIdentifier forKey:(id)kSecAttrAccount];
[searchDictionary setObject:serviceName forKey:(id)kSecAttrService];
return searchDictionary;
}
- (NSData *)searchKeychainCopyMatching:(NSString *)identifier {
NSMutableDictionary *searchDictionary = [self newSearchDictionary:identifier];
// Add search attributes
[searchDictionary setObject:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit];
// Add search return types
[searchDictionary setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData];
NSData *result = nil;
// OSStatus status =
SecItemCopyMatching((CFDictionaryRef)searchDictionary,(__bridge CFTypeRef *)&result);
OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)searchDictionary,
(void *)&result);
return result;
}
- (BOOL)createKeychainValue:(NSString *)password forIdentifier:(NSString *)identifier {
NSMutableDictionary *dictionary = [self newSearchDictionary:identifier];
NSData *passwordData = [password dataUsingEncoding:NSUTF8StringEncoding];
[dictionary setObject:passwordData forKey:(id)kSecValueData];
OSStatus status = SecItemAdd((CFDictionaryRef)dictionary, NULL);
if (status == errSecSuccess) {
return YES;
}
return NO;
}
仅靠iOS
无法实现此目的,但是您可以通过使用带有数据库的服务器来实现此目的,并且在首次运行该应用程序时,会将device's UDID
发送到您的server
; 如果服务器已经具有UDID
,则该应用程序已经安装。
当然,此解决方案确实需要用户具有Internet连接。
我认为,您将UDID发送到icloud Apple进行存储。 如果是第一次安装应用程序。 找不到icloud iphone,否则它将具有UDID。 您不需要服务器。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.