Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/wix/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何检查用户';iOS SDK中的s设备_Ios - Fatal编程技术网

如何检查用户';iOS SDK中的s设备

如何检查用户';iOS SDK中的s设备,ios,Ios,我正在尝试修复我的应用程序中的问题。我想要一种独特的方式来识别用户的手机。因此,对下列案件进行了审判 我知道,我们无法从用户设备获取电话IMEI和其他信息,请点击以下链接 我可以使用identifierForVendor,但每次安装应用程序时它都会发生变化 第三种选择是使用API来识别设备,但它只有iOS 11版本 请让我知道如何在Sim卡交换的情况下识别用户设备和临时禁用的用户帐户。一个可接受的解决方案是生成唯一的UUID并将其保存到Keychain,即使在删除应用程序后,Keych

我正在尝试修复我的应用程序中的问题。我想要一种独特的方式来识别用户的手机。因此,对下列案件进行了审判

  • 我知道,我们无法从用户设备获取电话IMEI和其他信息,请点击以下链接

  • 我可以使用identifierForVendor,但每次安装应用程序时它都会发生变化

  • 第三种选择是使用API来识别设备,但它只有iOS 11版本


请让我知道如何在Sim卡交换的情况下识别用户设备和临时禁用的用户帐户。

一个可接受的解决方案是生成唯一的UUID并将其保存到Keychain,即使在删除应用程序后,Keychain项仍然存在


/* DeviceUID.h
#import <Foundation/Foundation.h>

@interface DeviceUID : NSObject
+ (NSString *)uid;
@end
*/


// Device.m
#import "DeviceUID.h"

@import UIKit;

@interface DeviceUID ()

@property(nonatomic, strong, readonly) NSString *uidKey;
@property(nonatomic, strong, readonly) NSString *uid;

@end

@implementation DeviceUID

@synthesize uid = _uid;

#pragma mark - Public methods

+ (NSString *)uid {
    return [[[DeviceUID alloc] initWithKey:@"deviceUID"] uid];
}

#pragma mark - Instance methods

- (id)initWithKey:(NSString *)key {
    self = [super init];
    if (self) {
        _uidKey = key;
        _uid = nil;
    }
    return self;
}

/*! Returns the Device UID.
    The UID is obtained in a chain of fallbacks:
      - Keychain
      - NSUserDefaults
      - Apple IFV (Identifier for Vendor)
      - Generate a random UUID if everything else is unavailable
    At last, the UID is persisted if needed to.
 */
- (NSString *)uid {
    if (!_uid) _uid = [[self class] valueForKeychainKey:_uidKey service:_uidKey];
    if (!_uid) _uid = [[self class] valueForUserDefaultsKey:_uidKey];
    if (!_uid) _uid = [[self class] appleIFV];
    if (!_uid) _uid = [[self class] randomUUID];
    [self save];
    return _uid;
}

/*! Persist UID to NSUserDefaults and Keychain, if not yet saved
 */
- (void)save {
    if (![DeviceUID valueForUserDefaultsKey:_uidKey]) {
        [DeviceUID setValue:self.uid forUserDefaultsKey:_uidKey];
    }
    if (![DeviceUID valueForKeychainKey:_uidKey service:_uidKey]) {
        [DeviceUID setValue:self.uid forKeychainKey:_uidKey inService:_uidKey];
    }
}

#pragma mark - Keychain methods

/*! Create as generic NSDictionary to be used to query and update Keychain items.
 *  param1
 *  param2
 */
+ (NSMutableDictionary *)keychainItemForKey:(NSString *)key service:(NSString *)service {
    NSMutableDictionary *keychainItem = [[NSMutableDictionary alloc] init];
    keychainItem[(__bridge id)kSecClass] = (__bridge id)kSecClassGenericPassword;
    keychainItem[(__bridge id)kSecAttrAccessible] = (__bridge id)kSecAttrAccessibleAlways;
    keychainItem[(__bridge id)kSecAttrAccount] = key;
    keychainItem[(__bridge id)kSecAttrService] = service;
    return keychainItem;
}

/*! Sets
 *  param1
 *  param2
 */
+ (OSStatus)setValue:(NSString *)value forKeychainKey:(NSString *)key inService:(NSString *)service {
    NSMutableDictionary *keychainItem = [[self class] keychainItemForKey:key service:service];
    keychainItem[(__bridge id)kSecValueData] = [value dataUsingEncoding:NSUTF8StringEncoding];
    return SecItemAdd((__bridge CFDictionaryRef)keychainItem, NULL);
}

+ (NSString *)valueForKeychainKey:(NSString *)key service:(NSString *)service {
    OSStatus status;
    NSMutableDictionary *keychainItem = [[self class] keychainItemForKey:key service:service];
    keychainItem[(__bridge id)kSecReturnData] = (__bridge id)kCFBooleanTrue;
    keychainItem[(__bridge id)kSecReturnAttributes] = (__bridge id)kCFBooleanTrue;
    CFDictionaryRef result = nil;
    status = SecItemCopyMatching((__bridge CFDictionaryRef)keychainItem, (CFTypeRef *)&result);
    if (status != noErr) {
        return nil;
    }
    NSDictionary *resultDict = (__bridge_transfer NSDictionary *)result;
    NSData *data = resultDict[(__bridge id)kSecValueData];
    if (!data) {
        return nil;
    }
    return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
}

#pragma mark - NSUserDefaults methods

+ (BOOL)setValue:(NSString *)value forUserDefaultsKey:(NSString *)key {
    [[NSUserDefaults standardUserDefaults] setObject:value forKey:key];
    return [[NSUserDefaults standardUserDefaults] synchronize];
}

+ (NSString *)valueForUserDefaultsKey:(NSString *)key {
    return [[NSUserDefaults standardUserDefaults] objectForKey:key];
}

#pragma mark - UID Generation methods

+ (NSString *)appleIFA {
    NSString *ifa = nil;
    Class ASIdentifierManagerClass = NSClassFromString(@"ASIdentifierManager");
    if (ASIdentifierManagerClass) { // a dynamic way of checking if AdSupport.framework is available
        SEL sharedManagerSelector = NSSelectorFromString(@"sharedManager");
        id sharedManager = ((id (*)(id, SEL))[ASIdentifierManagerClass methodForSelector:sharedManagerSelector])(ASIdentifierManagerClass, sharedManagerSelector);
        SEL advertisingIdentifierSelector = NSSelectorFromString(@"advertisingIdentifier");
        NSUUID *advertisingIdentifier = ((NSUUID* (*)(id, SEL))[sharedManager methodForSelector:advertisingIdentifierSelector])(sharedManager, advertisingIdentifierSelector);
        ifa = [advertisingIdentifier UUIDString];
    }
    return ifa;
}

+ (NSString *)appleIFV {
    if(NSClassFromString(@"UIDevice") && [UIDevice instancesRespondToSelector:@selector(identifierForVendor)]) {
        // only available in iOS >= 6.0
        return [[UIDevice currentDevice].identifierForVendor UUIDString];
    }
    return nil;
}

+ (NSString *)randomUUID {
    if(NSClassFromString(@"NSUUID")) {
        return [[NSUUID UUID] UUIDString];
    }
    CFUUIDRef uuidRef = CFUUIDCreate(kCFAllocatorDefault);
    CFStringRef cfuuid = CFUUIDCreateString(kCFAllocatorDefault, uuidRef);
    CFRelease(uuidRef);
    NSString *uuid = [((__bridge NSString *) cfuuid) copy];
    CFRelease(cfuuid);
    return uuid;
}

@end

/*设备uid.h
#进口
@接口设备uid:NSObject
+(NSString*)uid;
@结束
*/
//设备
#导入“DeviceUID.h”
@进口UIKit;
@接口设备UID()
@属性(非原子、强、只读)NSString*uidKey;
@属性(非原子、强、只读)NSString*uid;
@结束
@实现设备UID
@合成uid=\u uid;
#pragma标记-公共方法
+(NSString*)uid{
返回[[[DeviceUID alloc]initWithKey:@“DeviceUID”]uid];
}
#pragma标记-实例方法
-(id)initWithKey:(NSString*)键{
self=[super init];
如果(自我){
_uidKey=key;
_uid=零;
}
回归自我;
}
/*! 返回设备UID。
UID是在一系列回退中获得的:
-钥匙链
-NSUserDefaults
-苹果IFV(供应商标识符)
-如果其他一切都不可用,则生成随机UUID
最后,如果需要,UID将被持久化。
*/
-(NSString*)uid{
如果(!\u uid)\u uid=[[self class]valueForKeychainKey:\u uidKey服务:\u uidKey];
如果(!\u uid)\u uid=[[self class]valueForUserDefaultsKey:\u uidKey];
如果(!\u uid)\u uid=[[self class]appleIFV];
如果(!\u uid)\u uid=[[self class]randomUUID];
[自救];
返回uid;
}
/*! 如果尚未保存,则将UID持久化为NSUserDefaults和Keychain
*/
-(无效)保存{
如果(![DeviceUID valueForUserDefaultsKey:\u uidKey]){
[DeviceUID设置值:self.uid for userdefaultskey:_uidKey];
}
if(![DeviceUID valueForKeychainKey:_uidKey服务:_uidKey]){
[设备uid设置值:self.uid forKeychainKey:_uidkeyin service:_uidKey];
}
}
#pragma标记-键链方法
/*! 创建通用NSDictionary,用于查询和更新密钥链项。
*参数1
*参数2
*/
+(NSMutableDictionary*)keychainItemForKey:(NSString*)密钥服务:(NSString*)服务{
NSMutableDictionary*keychainItem=[[NSMutableDictionary alloc]init];
keychainItem[(\uu桥id)kSecClass]=(\uu桥id)kSecClassGenericPassword;
keychainItem[(\u桥id)kSecAttrAccessible]=(\u桥id)ksecattraccessibleallways;
keychainItem[(_桥id)kSecAttrAccount]=键;
keychainItem[(uu桥id)kSecAttrService]=服务;
返回keychainItem;
}
/*! 设置
*参数1
*参数2
*/
+(OSStatus)setValue:(NSString*)值forKeychainKey:(NSString*)服务中的键:(NSString*)服务{
NSMutableDictionary*keychainItem=[[self-class]keychainItemForKey:key-service:service];
keychainItem[(_桥id)kSecValueData]=[值数据使用编码:NSUTF8StringEncoding];
返回SecItemAdd((uu桥CFDictionaryRef)keychainItem,NULL);
}
+(NSString*)valueForKeychainKey:(NSString*)密钥服务:(NSString*)服务{
骨状态;
NSMutableDictionary*keychainItem=[[self-class]keychainItemForKey:key-service:service];
keychainItem[(\u桥id)kSecReturnData]=(\u桥id)kCFBooleanTrue;
keychainItem[(\uu桥id)kSecReturnAttributes]=(\uu桥id)kCFBooleanTrue;
cfyref结果=零;
状态=SecItemCopyMatching((uu桥CFDictionaryRef)keychainItem,(CFTypeRef*)和结果);
如果(状态!=noErr){
返回零;
}
NSDictionary*ResultDisct=(\u桥\u传输NSDictionary*)结果;
NSData*data=resultDict[(桥id)kSecValueData];
如果(!数据){
返回零;
}
return[[NSString alloc]initWithData:数据编码:NSUTF8StringEncoding];
}
#pragma标记-NSUserDefaults方法
+(BOOL)setValue:(NSString*)userdefaultskey:(NSString*)键的值{
[[NSUserDefaults standardUserDefaults]setObject:value-forKey:key];
返回[[NSUserDefaults standardUserDefaults]同步];
}
+(NSString*)userdefaultskey的值:(NSString*)键{
返回[[NSUserDefaults standardUserDefaults]objectForKey:key];
}
#pragma标记-UID生成方法
+(NSString*)appleIFA{
NSString*ifa=nil;
类ASIdentifierManagerClass=NSClassFromString(@“ASIdentifierManager”);
if(asiIdentifierManagerClass){//检查AdSupport.framework是否可用的动态方法
SEL sharedManagerSelector=NSSelectorFromString(@“sharedManager”);
id sharedManager=((id(*)(id,SEL))[ASIdentifierManagerClass方法用于选择器:SharedManagerSelect])(ASIdentifierManagerClass,SharedManagerSelect);
SEL advertisingIdentifier Selector=NSSelectorFromString(@“advertisingIdentifier”);
NSUID*advertisingIdentifier=((NSUID*(*)(id,SEL))[sharedManager方法供选择者:advertisingIdentifierSelector])(sharedManager,advertisingIdentifierSelector);
ifa=[advertisingIdentifier UUIString];
}
返回ifa;
}
+(NSString*)appleIFV{
if(NSClassFromString(@“UIDevice”)&&[UIDevice InstanceRespondToSelector:@selector(identifierForVendor)]){
//仅在iOS>=6.0版本中可用
返回[[UIDevice currentDevice].identifierForVendor UUIString];
}
返回零;
}
+(NSString*)随机UUID{
if(NSClassFromString(@“nsuid”)){
返回[[NSUID UUID]UUIString];
}
CFUUIDRef uuidRef=cfuuiddcreate(kcfolocatordefault);
CFStringRef cfuuid=CFUUIDCreateString(kCFAllocatorDefault,uuidRef);
CFRelease(uuidRef);
NSString*uuid=[((uu桥NSString*)cfuuid)拷贝];
cfuuid;
返回uui
let uuid = UIDevice.current.identifierForVendor?.uuidString
KeychainWrapper.standard.set(uuid, forKey: "appUUID")
let uuid = KeychainWrapper.standard.string(forKey: "appUUID")