Unity在IOS移动端获取用户唯一标识

前言

在移动端游戏开发时,我们常常会有获取一个唯一且固定不变的用户标识的需求

unity本身是提供了一个唯一标识(SystemInfo.deviceUniqueIdentifier)供我们使用的,在安卓设备上,我们只要保证应用的签名不变,这个标识基本就不会改变。但在IOS设备上这个标识却会随着用户更新系统或者重装应用而发生变化

当然网上有特别多的实现方案,在此仅分享一个博主常用且在线上产品验证有效的方案

IDFV

IOS官方文档
用来标识应用程序开发商的唯一标识符,且必然能获取到,无需请求用户权限。对于来自同一开发商并在同一设备上运行的应用,此属性的值相同。但卸载重装可能会可能导致该值发生变化

例如,应用A和应用B均来自同一个开发商,在某个IOS设备上安装或卸载这两个应用,以下不同情况会有不同结果

  • 如果已安装A,A获取到的是IDFV_A,再安装B,B获取到的是IDFV_B,此时IDFV_A和IDFV_B相同
  • 如果已安装A,A获取到的是IDFV_A,再安装B,B获取到的是IDFV_B,然后卸载重装A,A获取到的还是IDFV_A,且IDFV_A和IDFV_B相同
  • 如果已安装A,A获取到的是IDFV_A,再安装B,B获取到的是IDFV_B,然后同时卸载A和B,接下来再重新安装A,A获取到的是IDFV_A_1,IDFV_A和IDFV_A_1不一定相同。此时如果再安装B,B获取到的是IDFV_B_1,IDFV_B_1和IDFV_A_1还是相同的

IOS钥匙串-Keychain

苹果官方提供的一种存储机制,主要用于存储一些敏感信息(如密码、密钥等),不会随应用卸载而被清除。当然实现方式也非常多,如果没有合适的实现方式,可以使用以下源码
实现源码

IOS唯一标识实现方案

本方案还是使用IDFV作为唯一标识,只不过并非每次重新启动应用都去获取。

在应用启动时,首先去PlayerPrefs中查询是否存储了该应用的IDFV。如果PlayerPrefs中存在,则直接使用,如果PlayerPrefs中不存在,则去Keychain中查询。如果Keychain中存在,则直接使用并将其存储到PlayerPrefs中,如果Keychain中不存在,则需要去获取IDFV并将其同时储存到PlayerPrefs和Keychain中

简单的源码实现

public static string GetUUID_IOS()
        {
            const string IdfvKey = "IdfvIOS";
            KeychainWrapper keychainWrapper = new KeychainWrapper();
            string uuid = PlayerPrefs.GetString(IdfvKey, "");
            if (string.IsNullOrEmpty(uuid))
            {
                uuid = keychainWrapper.GetStringForKey(IdfvKey);
                if (string.IsNullOrEmpty(uuid))
                {
                    uuid = UnityEngine.iOS.Device.vendorIdentifier;
                    keychainWrapper.SetStringForKey(IdfvKey, uuid);
                }
                PlayerPrefs.SetString(IdfvKey, uuid);
            }
            else
            {
                //防止钥匙串中未存储
                if (string.IsNullOrEmpty(keychainWrapper.GetStringForKey(IdfvKey)))
                {
                    keychainWrapper.SetStringForKey(IdfvKey, uuid);
                }
            }
            return uuid;
        }

这样就能保证以后每次使用的均是首次启动应用时保存的IDFV。当然不排除一些极特殊的情况(比如刷机重装系统之类的)导致丢失的,但这不在我们本方案的考虑范围内,因为这发生的概率极低且并非我们能避免的。如果想要保证百分百唯一且不丢失,最好的方案还是引导用户绑定第三方账号

  • 21
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Unity中,可以使用Keychain来存储和获取设备唯一标识符。以下是一些示例代码,可以帮助你在iOS获取一个永远不变的标记: ```csharp using System.Runtime.InteropServices; using UnityEngine; public static class DeviceInfo { #if UNITY_IOS [DllImport("__Internal")] private static extern string _GetDeviceID(); #endif public static string GetDeviceID() { string deviceID = ""; #if UNITY_IOS deviceID = _GetDeviceID(); #endif if (string.IsNullOrEmpty(deviceID)) { Debug.LogError("Failed to get device ID"); } return deviceID; } } ``` 然后,在Objective-C中实现_GetDeviceID()方法: ```objective-c #import <Foundation/Foundation.h> #import <Security/Security.h> #include <sys/sysctl.h> NSString* GetDeviceID() { NSString *serviceName = [[NSBundle mainBundle] bundleIdentifier]; NSString *accountName = @"DeviceID"; NSDictionary *query = @{ (__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword, (__bridge id)kSecAttrService: serviceName, (__bridge id)kSecAttrAccount: accountName, (__bridge id)kSecReturnData: @YES }; CFTypeRef dataTypeRef = NULL; OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &dataTypeRef); if (status == noErr && dataTypeRef != NULL) { NSData *data = (__bridge NSData *)dataTypeRef; NSString *deviceID = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; return deviceID; } NSString *deviceID = [GetUUID() lowercaseString]; NSData *data = [deviceID dataUsingEncoding:NSUTF8StringEncoding]; query = @{ (__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword, (__bridge id)kSecAttrService: serviceName, (__bridge id)kSecAttrAccount: accountName, (__bridge id)kSecValueData: data }; status = SecItemAdd((__bridge CFDictionaryRef)query, NULL); if (status != noErr) { NSLog(@"Failed to save device ID"); } return deviceID; } NSString* GetUUID() { CFUUIDRef uuidRef = CFUUIDCreate(kCFAllocatorDefault); CFStringRef uuidStringRef = CFUUIDCreateString(kCFAllocatorDefault, uuidRef); NSString *uuid = (__bridge NSString *)uuidStringRef; CFRelease(uuidRef); CFRelease(uuidStringRef); return uuid; } ``` 这个方法将使用Keychain来存储设备唯一标识符。如果设备上没有存储标识符,则会生成一个新的唯一标识符并将其存储在Keychain中。如果设备上已经存在标识符,则直接从Keychain中获取它。这样,即使用户删除并重新安装应用程序,设备唯一标识符也将保持不变。 请注意,此方法需要在Unity中使用iOS插件来实现。将上述Objective-C代码放入一个名为"DeviceID.m"的文件中,并将其添加到Unity项目的Plugins/iOS目录中即可。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值