507

UIDeviceのuniqueIdentifierプロパティがiOS5で非推奨になり、iOS7以降では使用できなくなったことが明らかになりました。代替の方法やプロパティは利用できないか、今後提供されないようです。

既存のアプリの多くは、特定のデバイスを一意に識別するためにこのプロパティに強く依存しています。今後、この問題にどのように対処できるでしょうか。

2011〜2012年のドキュメントからの提案は次のとおりです。

特別な考慮事項

uniqueIdentifierプロパティは使用しないでください。アプリに固有の一意の識別子を作成するには、CFUUIDCreate関数を呼び出してを作成し、クラスUUIDを使用してデフォルトのデータベースに書き込みます。NSUserDefaults

ただし、ユーザーがアプリをアンインストールして再インストールした場合、この値は同じにはなりません。

4

32 に答える 32

275

によって作成された UUIDCFUUIDCreate 、ユーザーがアプリをアンインストールして再インストールした場合に一意です。毎回新しいものを取得します。

ただし、一意ではなく、ユーザーがアプリをアンインストールして再インストールしても変わらないようにしたい場合があります。最も信頼できるデバイスごとの識別子は MAC アドレスと思われるため、これには少し手間がかかります。MACを照会して、それを UUID として使用できます。

編集:もちろん、同じインターフェースのMACを常に照会する必要があります。私は最善の策だと思いen0ます。インターフェイスに IP がない場合やダウンしている場合でも、MAC は常に存在します。

編集 2:他の人が指摘したように、iOS 6 以降の推奨ソリューションは-[UIDevice identifierForVendor]です。ほとんどの場合、古いもののドロップイン置換として使用できるはずです-[UIDevice uniqueIdentifier](ただし、アプリの初回起動時に作成される UUID は、Apple が使用を望んでいるようです)。

編集 3:したがって、この主要なポイントはコメント ノイズで失われません: MACを UUID として使用せず、 MAC を使用してハッシュを作成します。そのハッシュは、再インストールやアプリ間であっても、常に同じ結果を生成します (ハッシュが同じ方法で行われた場合)。とにかく、最近 (2013 年) では、iOS < 6.0 で「安定した」デバイス識別子が必要な場合を除いて、これはもう必要ありません。

編集 4: iOS 7 では、IDスキームのベースとしてMAC を具体的に阻止するために MAC を照会するときに、Apple は常に固定値を返すようになりました。したがって、-[UIDevice identifierForVendor]を使用するか、インストールごとの UUID を作成する必要があります。

于 2011-08-09T08:37:32.697 に答える
92

UDIDすでにApple の代替品を使用できます。親切な人 gekitz は、デバイスの MAC アドレスとバンドル ID に基づいてUIDevice何らかの種類を生成するカテゴリを作成しました。UDID

コードはgithubで見つけることができます

于 2011-08-22T08:40:01.243 に答える
62

@moonlightによって提案されたリンクに基づいて、私はいくつかのテストを行いましたが、それが最善の解決策のようです。@DarkDustが言うように、メソッドen0は常に利用可能なものをチェックします。(MAC + CFBundleIdentifierのMD5) と(MACのMD5)の
2つのオプションがあり、これらは常に同じ値を返します。 私が(実際のデバイスで)行ったテストの下:
uniqueDeviceIdentifier
uniqueGlobalDeviceIdentifier

#import "UIDevice+IdentifierAddition.h"

NSLog(@"%@",[[UIDevice currentDevice] uniqueDeviceIdentifier]);
NSLog(@"%@",[[UIDevice currentDevice] uniqueGlobalDeviceIdentifier]);

XXXX21f1f19edff198e2a2356bf4XXXX-(WIFI)UDID
XXXX7dc3c577446a2bcbd77935bdXXXX-(WIFI)GlobalAppUDID

XXXX21f1f19edff198e2a2356bf4XXXX-(3G)UDID
XXXX7dc3c577446a2bcbd77935bdXXXX-(3G)GlobalAppUDID

XXXX21f1f19edff198e2a2356bf4XXXX-(GPRS)UDID
XXXX7dc3c577446a2bcbd77935bdXXXX-(GPRS)GlobalAppUDID

XXXX21f1f19edff198e2a2356bf4XXXX-(機内モード)UDID
XXXX7dc3c577446a2bcbd77935bdXXXX-(機内モード)GlobalAppUDID

XXXX21f1f19edff198e2a2356bf4XXXX-(Wi-Fi)アプリを削除して再インストールした後XXXX7dc3c577446a2bcbd77935bdXXXX(Wi-Fi)アプリを削除してインストールした後

お役に立てば幸いです。

編集:
他の人が指摘したように、iOS 7のこのソリューションはuniqueIdentifier使用できなくなり、MACアドレスのクエリは常に02:00:00:00:00:00を返すため、もはや役に立ちません

于 2011-10-24T09:32:16.320 に答える
58

これをチェックして、

によって作成されNSUserDefaultsたストアに、クラスの代わりにキーチェーンを使用できます。UUIDCFUUIDCreate

このようにして、再インストールによる再作成を回避し、ユーザーがアンインストールして再度再インストールしても、同じアプリケーションでUUID常に同じものを取得できます。UUID

UUIDユーザーがデバイスをリセットしたときに再作成されます。

このメソッドをSFHFKeychainUtilsで試してみましたが、魅力的です。

于 2012-03-06T15:16:50.297 に答える
49

独自の UUID を作成し、キーチェーンに保存します。したがって、アプリがアンインストールされても存続します。多くの場合、ユーザーがデバイス間で移行しても (フル バックアップと別のデバイスへの復元など) 保持されます。

あなたに関する限り、事実上、それは一意のユーザー識別子になります。(デバイス識別子よりも優れています)。

例:

asを作成するためのカスタムメソッドを定義してUUIDいます:

- (NSString *)createNewUUID 
{
    CFUUIDRef theUUID = CFUUIDCreate(NULL);
    CFStringRef string = CFUUIDCreateString(NULL, theUUID);
    CFRelease(theUUID);
    return [(NSString *)string autorelease];
}

KEYCHAINその後、アプリの最初の起動時に保存できます。そのため、最初の起動後はキーチェーンから簡単に使用でき、再生成する必要はありません。キーチェーンを使用して保存する主な理由は次のとおりです。キーUUIDチェーンに設定すると、ユーザーがアプリを完全にアンインストールしてから再度インストールしても、保持されます。. したがって、これは永続的な保存方法です。つまり、キーは常に一意になります。

     #import "SSKeychain.h"
     #import <Security/Security.h>

アプリケーションの起動時に、次のコードを含めます。

 // getting the unique key (if present ) from keychain , assuming "your app identifier" as a key
       NSString *retrieveuuid = [SSKeychain passwordForService:@"your app identifier" account:@"user"];
      if (retrieveuuid == nil) { // if this is the first time app lunching , create key for device
        NSString *uuid  = [self createNewUUID];
// save newly created key to Keychain
        [SSKeychain setPassword:uuid forService:@"your app identifier" account:@"user"];
// this is the one time process
}

sskeychain からSSKeychain.mおよび .h ファイルをダウンロードし、SSKeychain.m および .h ファイル をプロジェクトにドラッグして、「Security.framework」をプロジェクトに追加します。後で UUID を使用するには、次のようにします。

NSString *retrieveuuid = [SSKeychain passwordForService:@"your app identifier" account:@"user"];
于 2012-09-20T11:03:31.030 に答える
17

おそらくあなたは使用することができます:

[UIDevice currentDevice].identifierForVendor.UUIDString

Apple のドキュメントでは、identifierForVender について次のように説明されています。

このプロパティの値は、同じデバイスで実行されている同じベンダーのアプリでも同じです。異なるベンダーから提供された同じデバイス上のアプリと、ベンダーに関係なく異なるデバイス上のアプリでは、異なる値が返されます。

于 2013-01-15T18:43:44.797 に答える
15

OpenUDID非推奨の のドロップイン代替である which の使用を検討することをお勧めしUDIDます。

基本的に、 に一致させるUDIDには、次の機能が必要です。

  1. 一意または十分に一意 (低確率の衝突はおそらく非常に許容されます)
  2. 再起動、復元、アンインストールにわたる持続性
  3. さまざまなベンダーのアプリで利用可能 (CPI ネットワーク経由でユーザーを獲得するのに役立ちます) -

OpenUDID上記を満たし、後で検討するためのオプトアウトメカニズムが組み込まれています.

対応する GitHub を指しているhttp://OpenUDID.orgを確認してください。お役に立てれば!

補足として、私はMACアドレスの代替案を敬遠します. MAC アドレスは魅力的で普遍的な解決策のように見えますが、この容易に手に入る果実が毒されていることを確認してください。MAC アドレスは非常に機密性が高く、Apple は、「このアプリを送信」と言う前に、これへのアクセスを非推奨にする可能性があります... MAC ネットワーク アドレスは、プライベート LAN (WLAN) またはその他の仮想プライベート上の特定のデバイスを認証するために使用されます。ネットワーク (VPN)。..以前の UDID よりもさらに高感度です。

于 2012-03-28T19:16:06.613 に答える
12

Apple がこの変更で多くの人を悩ませたことは間違いない。私は iOS 用の簿記アプリを開発しており、さまざまなデバイスで行われた変更を同期するオンライン サービスを利用しています。このサービスは、すべてのデバイスと、それらに伝達する必要がある変更のデータベースを維持します。したがって、どのデバイスがどれであるかを知ることが重要です。私は UIDevice uniqueIdentifier を使用してデバイスを追跡しています。その価値について、ここに私の考えを示します。

  • UUID を生成してユーザーのデフォルトに保存しますか? ユーザーがアプリを削除すると、これは持続しないため、良くありません。後で再度インストールする場合、オンライン サービスは新しいデバイス レコードを作成しないようにする必要があります。これにより、サーバー上のリソースが浪費され、同じものを含むデバイスのリストが 2 回以上作成されます。ユーザーがアプリを再インストールすると、複数の「ボブの iPhone」が表示されます。

  • UUID を生成してキーチェーンに保存しますか? アプリをアンインストールしても持続するので、これは私の計画でした。ただし、iTunes バックアップを新しい iOS デバイスに復元する場合、バックアップが暗号化されている場合はキーチェーンが転送されます。これにより、古いデバイスと新しいデバイスの両方が稼働中の場合、2 つのデバイスに同じデバイス ID が含まれる可能性があります。これらは、デバイス名が同じであっても、オンライン サービスでは 2 つのデバイスとして表示される必要があります。

  • MAC アドレスとバンドル ID のハッシュを生成しますか? これは、私が必要とするものに対する最良の解決策のようです。バンドル ID を使用してハッシュすることにより、生成されたデバイス ID ではデバイスをアプリ間で追跡できなくなり、アプリとデバイスの組み合わせに対して一意の ID が取得されます。

Apple 自身のドキュメントが、システム MAC アドレスとバンドル ID およびバージョンのハッシュを計算することによるMac App Store のレシートの検証に言及していることに注意してください。したがって、これはポリシーで許可されているようですが、アプリのレビューを通過するかどうかはまだわかりません.

于 2012-04-13T15:10:42.960 に答える
12

iOS 6 の場合、Apple はNSUUID クラスの使用を推奨しているようです。

プロパティのUIDeviceドキュメントのメッセージから:uniqueIdentifier

iOS 5.0 で廃止されました。必要に応じて、代わりにこのクラスの identifierForVendor プロパティまたは ASIdentifierManager クラスの AdvertisingIdentifier プロパティを使用するか、NSUUID クラスの UUID メソッドを使用して UUID を作成し、それをユーザー デフォルト データベースに書き込みます。

于 2012-10-01T09:27:11.027 に答える
7

また、デバイスのMACアドレスとApp Bundle Identifierを利用して、UDIDの代わりに使用できる一意のIDをアプリケーションで生成する、このオープンソースライブラリuniqueIdentifier(実際には2つの単純なカテゴリ)に切り替えることをお勧めします。

UDIDとは異なり、この数はアプリごとに異なることに注意してください。

NSString含まれているカテゴリとカテゴリをインポートして、次のようUIDeviceに呼び出す必要があります。[[UIDevice currentDevice] uniqueDeviceIdentifier]

#import "UIDevice+IdentifierAddition.h"
#import "NSString+MD5Addition.h"
NSString *iosFiveUDID = [[UIDevice currentDevice] uniqueDeviceIdentifier]

ここのGithubで見つけることができます:

iOS5用のUniqueIdentifierを備えたUIDevice


カテゴリは次のとおりです(.mファイルのみ-ヘッダーについてはgithubプロジェクトを確認してください):

UIDevice + IdentityAddition.m

#import "UIDevice+IdentifierAddition.h"
#import "NSString+MD5Addition.h"

#include <sys/socket.h> // Per msqr
#include <sys/sysctl.h>
#include <net/if.h>
#include <net/if_dl.h>

@interface UIDevice(Private)

- (NSString *) macaddress;

@end

@implementation UIDevice (IdentifierAddition)

////////////////////////////////////////////////////////////////////////////////
#pragma mark -
#pragma mark Private Methods

// Return the local MAC addy
// Courtesy of FreeBSD hackers email list
// Accidentally munged during previous update. Fixed thanks to erica sadun & mlamb.
- (NSString *) macaddress{
    
    int                 mib[6];
    size_t              len;
    char                *buf;
    unsigned char       *ptr;
    struct if_msghdr    *ifm;
    struct sockaddr_dl  *sdl;
    
    mib[0] = CTL_NET;
    mib[1] = AF_ROUTE;
    mib[2] = 0;
    mib[3] = AF_LINK;
    mib[4] = NET_RT_IFLIST;
    
    if ((mib[5] = if_nametoindex("en0")) == 0) {
        printf("Error: if_nametoindex error\n");
        return NULL;
    }
    
    if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) {
        printf("Error: sysctl, take 1\n");
        return NULL;
    }
    
    if ((buf = malloc(len)) == NULL) {
        printf("Could not allocate memory. error!\n");
        return NULL;
    }
    
    if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) {
        printf("Error: sysctl, take 2");
        return NULL;
    }
    
    ifm = (struct if_msghdr *)buf;
    sdl = (struct sockaddr_dl *)(ifm + 1);
    ptr = (unsigned char *)LLADDR(sdl);
    NSString *outstring = [NSString stringWithFormat:@"%02X:%02X:%02X:%02X:%02X:%02X", 
                           *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4), *(ptr+5)];
    free(buf);
    
    return outstring;
}

////////////////////////////////////////////////////////////////////////////////
#pragma mark -
#pragma mark Public Methods

- (NSString *) uniqueDeviceIdentifier{
    NSString *macaddress = [[UIDevice currentDevice] macaddress];
    NSString *bundleIdentifier = [[NSBundle mainBundle] bundleIdentifier];  
    NSString *stringToHash = [NSString stringWithFormat:@"%@%@",macaddress,bundleIdentifier];
    NSString *uniqueIdentifier = [stringToHash stringFromMD5];  
    return uniqueIdentifier;
}

- (NSString *) uniqueGlobalDeviceIdentifier{
    NSString *macaddress = [[UIDevice currentDevice] macaddress];
    NSString *uniqueIdentifier = [macaddress stringFromMD5];    
    return uniqueIdentifier;
}

@end

NSString + MD5Addition.m:

#import "NSString+MD5Addition.h"
#import <CommonCrypto/CommonDigest.h>

@implementation NSString(MD5Addition)

- (NSString *) stringFromMD5{
    
    if(self == nil || [self length] == 0)
        return nil;
    
    const char *value = [self UTF8String];
    
    unsigned char outputBuffer[CC_MD5_DIGEST_LENGTH];
    CC_MD5(value, strlen(value), outputBuffer);
    
    NSMutableString *outputString = [[NSMutableString alloc] initWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
    for(NSInteger count = 0; count < CC_MD5_DIGEST_LENGTH; count++){
        [outputString appendFormat:@"%02x",outputBuffer[count]];
    }
    return [outputString autorelease];
}

@end
于 2011-10-30T18:17:24.600 に答える
5

このコードから達成できます: UIDevice-with-UniqueIdentifier-for-iOS-5

于 2012-10-31T08:45:01.360 に答える
4

UIDevice identifierForVendoriOS 6 で導入されたものは、あなたの目的に適しています。

identifierForVendorアプリのベンダーに対してデバイスを一意に識別する英数字の文字列です。(読み取り専用)

@property(nonatomic, readonly, retain) NSUUID *identifierForVendor

このプロパティの値は、同じデバイスで実行されている同じベンダーのアプリでも同じです。異なるベンダーから提供された同じデバイス上のアプリと、ベンダーに関係なく異なるデバイス上のアプリでは、異なる値が返されます。

iOS 6.0 以降で利用可能で、で宣言されていますUIDevice.h

iOS 5 については、このリンクを参照してくださいUIDevice-with-UniqueIdentifier-for-iOS-5

于 2013-04-08T11:56:40.930 に答える
4

上記の SSKeychain とコードを使用します。コピー/貼り付けするコードは次のとおりです (SSKeychain モジュールを追加します)。

+(NSString *) getUUID {

//Use the bundle name as the App identifier. No need to get the localized version.

NSString *Appname = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"];    

//Check if we have UUID already

NSString *retrieveuuid = [SSKeychain passwordForService:Appname account:@"user"];

if (retrieveuuid == NULL)
{

    //Create new key for this app/device

    CFUUIDRef newUniqueId = CFUUIDCreate(kCFAllocatorDefault);

    retrieveuuid = (__bridge_transfer NSString*)CFUUIDCreateString(kCFAllocatorDefault, newUniqueId);

    CFRelease(newUniqueId);

    //Save key to Keychain
    [SSKeychain setPassword:retrieveuuid forService:Appname account:@"user"];
}

return retrieveuuid;

}

于 2013-09-04T12:09:16.180 に答える
4

MAC アドレスはスプーフィングされる可能性があるため、コンテンツを特定のユーザーに関連付けたり、ブラックリストなどのセキュリティ機能を実装したりするために、このようなアプローチは役に立たなくなります。

さらなる調査の結果、現在のところ適切な代替手段がないままになっているようです。Apple が決定を再考することを真剣に願っています。

Apple にこのトピックについて電子メールを送信するか、バグや機能のリクエストを提出することをお勧めします。Apple は開発者にとっての完全な結果を認識していない可能性があるからです。

于 2011-08-10T12:12:08.153 に答える
3

次のコードは、UDID を取得するのに役立ちます。

        udid = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
        NSLog(@"UDID : %@", udid);
于 2013-08-09T18:40:49.057 に答える
2

iOS 6 以降、RFC4122NSUUIDに準拠したクラスがあります。

Apple リンク : NSUUID の apple_ref

于 2012-10-17T11:57:53.137 に答える
1

Swift 3.0 の場合は、以下のコードを使用してください。

let deviceIdentifier: String = (UIDevice.current.identifierForVendor?.uuidString)!
NSLog("output is : %@", deviceIdentifier)
于 2016-09-17T05:22:15.503 に答える
1

使用できます

NSString *sID = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];

これは、すべてのアプリケーションでデバイスに固有のものです。

于 2014-02-25T05:34:33.293 に答える
1

UDID を取得する有効な方法:

  1. 2 つのページでアプリ内の Web サーバーを起動します。1 つは特別に細工された MobileConfiguration プロファイルを返し、もう 1 つは UDID を収集する必要があります。詳細はこちらこちらこちら
  2. アプリ内から Mobile Safari の最初のページを開くと、設定プロファイルのインストールを求める Settings.app にリダイレクトされます。プロファイルをインストールすると、UDID が 2 番目の Web ページに送信され、アプリ内からアクセスできるようになります。(Settings.app には、必要な資格とさまざまなサンドボックス ルールがすべて含まれています)。

RoutingHTTPServerを使用した例:

import UIKit
import RoutingHTTPServer

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    var bgTask = UIBackgroundTaskInvalid
    let server = HTTPServer()

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        application.openURL(NSURL(string: "http://localhost:55555")!)
        return true
    }

    func applicationDidEnterBackground(application: UIApplication) {
        bgTask = application.beginBackgroundTaskWithExpirationHandler() {
            dispatch_async(dispatch_get_main_queue()) {[unowned self] in
                application.endBackgroundTask(self.bgTask)
                self.bgTask = UIBackgroundTaskInvalid
            }
        }
    }
}

class HTTPServer: RoutingHTTPServer {
    override init() {
        super.init()
        setPort(55555)
        handleMethod("GET", withPath: "/") {
            $1.setHeader("Content-Type", value: "application/x-apple-aspen-config")
            $1.respondWithData(NSData(contentsOfFile: NSBundle.mainBundle().pathForResource("udid", ofType: "mobileconfig")!)!)
        }
        handleMethod("POST", withPath: "/") {
            let raw = NSString(data:$0.body(), encoding:NSISOLatin1StringEncoding) as! String
            let plistString = raw.substringWithRange(Range(start: raw.rangeOfString("<?xml")!.startIndex,end: raw.rangeOfString("</plist>")!.endIndex))
            let plist = NSPropertyListSerialization.propertyListWithData(plistString.dataUsingEncoding(NSISOLatin1StringEncoding)!, options: .allZeros, format: nil, error: nil) as! [String:String]

            let udid = plist["UDID"]! 
            println(udid) // Here is your UDID!

            $1.statusCode = 200
            $1.respondWithString("see https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/iPhoneOTAConfiguration/ConfigurationProfileExamples/ConfigurationProfileExamples.html")
        }
        start(nil)
    }
}

の内容は次のudid.mobileconfigとおりです。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <key>PayloadContent</key>
        <dict>
            <key>URL</key>
            <string>http://localhost:55555</string>
            <key>DeviceAttributes</key>
            <array>
                <string>IMEI</string>
                <string>UDID</string>
                <string>PRODUCT</string>
                <string>VERSION</string>
                <string>SERIAL</string>
            </array>
        </dict>
        <key>PayloadOrganization</key>
        <string>udid</string>
        <key>PayloadDisplayName</key>
        <string>Get Your UDID</string>
        <key>PayloadVersion</key>
        <integer>1</integer>
        <key>PayloadUUID</key>
        <string>9CF421B3-9853-9999-BC8A-982CBD3C907C</string>
        <key>PayloadIdentifier</key>
        <string>udid</string>
        <key>PayloadDescription</key>
        <string>Install this temporary profile to find and display your current device's UDID. It is automatically removed from device right after you get your UDID.</string>
        <key>PayloadType</key>
        <string>Profile Service</string>
    </dict>
</plist>

プロファイルのインストールは失敗します (期待される応答を実装することはしませんでした。ドキュメントを参照してください) が、アプリは正しい UDID を取得します。また、 mobileconfig にも署名する必要があります。

于 2015-06-04T17:55:30.743 に答える
1

Apple は iOS 11 に DeviceCheck と呼ばれる新しいフレームワークを追加しました。これにより、一意の識別子を非常に簡単に取得できます。詳細については、このフォームをお読みください。 https://medium.com/@santoshbotre01/unique-identifier-for-the-ios-devices-590bb778290d

于 2017-08-24T05:28:41.303 に答える
0

NSLog(@"%@",[[UIDevice currentDevice]identifierForVendor]);

于 2016-12-30T16:24:12.047 に答える
0

代替案を探しているときに、誰かがこの質問に出くわした場合。IDManager私はクラスでこのアプローチに従いました。これはさまざまなソリューションからのコレクションです。KeyChainUtil は、キーチェーンから読み取るラッパーです。hashed MAC addressを一種の一意の ID として使用することもできます。

/*  Apple confirmed this bug in their system in response to a Technical Support Incident 
    request. They said that identifierForVendor and advertisingIdentifier sometimes 
    returning all zeros can be seen both in development builds and apps downloaded over the 
    air from the App Store. They have no work around and can't say when the problem will be fixed. */
#define kBuggyASIID             @"00000000-0000-0000-0000-000000000000"

+ (NSString *) getUniqueID {
    if (NSClassFromString(@"ASIdentifierManager")) {
        NSString * asiID = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
        if ([asiID compare:kBuggyASIID] == NSOrderedSame) {
            NSLog(@"Error: This device return buggy advertisingIdentifier.");
            return [IDManager getUniqueUUID];
        } else {
            return asiID;
        }

    } else {
        return [IDManager getUniqueUUID];
    }
}


+ (NSString *) getUniqueUUID {
    NSError * error;
    NSString * uuid = [KeychainUtils getPasswordForUsername:kBuyassUser andServiceName:kIdOgBetilngService error:&error];
    if (error) {
        NSLog(@"Error geting unique UUID for this device! %@", [error localizedDescription]);
        return nil;
    }
    if (!uuid) {
        DLog(@"No UUID found. Creating a new one.");
        uuid = [IDManager GetUUID];
        uuid = [Util md5String:uuid];
        [KeychainUtils storeUsername:USER_NAME andPassword:uuid forServiceName:SERVICE_NAME updateExisting:YES error:&error];
        if (error) {
            NSLog(@"Error getting unique UUID for this device! %@", [error localizedDescription]);
            return nil;
        }
    }
    return uuid;
}

/* NSUUID is after iOS 6. */
+ (NSString *)GetUUID
{
    CFUUIDRef theUUID = CFUUIDCreate(NULL);
    CFStringRef string = CFUUIDCreateString(NULL, theUUID);
    CFRelease(theUUID);
    return [(NSString *)string autorelease];
}

#pragma mark - MAC address
// Return the local MAC addy
// Courtesy of FreeBSD hackers email list
// Last fallback for unique identifier
+ (NSString *) getMACAddress
{
    int                 mib[6];
    size_t              len;
    char                *buf;
    unsigned char       *ptr;
    struct if_msghdr    *ifm;
    struct sockaddr_dl  *sdl;

    mib[0] = CTL_NET;
    mib[1] = AF_ROUTE;
    mib[2] = 0;
    mib[3] = AF_LINK;
    mib[4] = NET_RT_IFLIST;

    if ((mib[5] = if_nametoindex("en0")) == 0) {
        printf("Error: if_nametoindex error\n");
        return NULL;
    }

    if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) {
        printf("Error: sysctl, take 1\n");
        return NULL;
    }

    if ((buf = malloc(len)) == NULL) {
        printf("Error: Memory allocation error\n");
        return NULL;
    }

    if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) {
        printf("Error: sysctl, take 2\n");
        free(buf); // Thanks, Remy "Psy" Demerest
        return NULL;
    }

    ifm = (struct if_msghdr *)buf;
    sdl = (struct sockaddr_dl *)(ifm + 1);
    ptr = (unsigned char *)LLADDR(sdl);
    NSString *outstring = [NSString stringWithFormat:@"%02X:%02X:%02X:%02X:%02X:%02X", *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4), *(ptr+5)];

    free(buf);
    return outstring;
}

+ (NSString *) getHashedMACAddress
{
    NSString * mac = [IDManager getMACAddress];
    return [Util md5String:mac];
}

+ (NSString *)md5String:(NSString *)plainText
{
    if(plainText == nil || [plainText length] == 0)
        return nil;

    const char *value = [plainText UTF8String];
    unsigned char outputBuffer[CC_MD5_DIGEST_LENGTH];
    CC_MD5(value, strlen(value), outputBuffer);

    NSMutableString *outputString = [[NSMutableString alloc] initWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
    for(NSInteger count = 0; count < CC_MD5_DIGEST_LENGTH; count++){
        [outputString appendFormat:@"%02x",outputBuffer[count]];
    }
    NSString * retString = [NSString stringWithString:outputString];
    [outputString release];
    return retString;
}
于 2013-05-13T15:08:18.423 に答える
0
+ (NSString *) getUniqueUUID {
    NSError * error;
    NSString * uuid = [KeychainUtils getPasswordForUsername:kBuyassUser andServiceName:kIdOgBetilngService error:&error];
    if (error) {
    NSLog(@"Error geting unique UUID for this device! %@", [error localizedDescription]);
    return nil;
    }
    if (!uuid) {
        DLog(@"No UUID found. Creating a new one.");
        uuid = [IDManager GetUUID];
        uuid = [Util md5String:uuid];
        [KeychainUtils storeUsername:USER_NAME andPassword:uuid forServiceName:SERVICE_NAME updateExisting:YES error:&error];
        if (error) {
            NSLog(@"Error getting unique UUID for this device! %@", [error localizedDescription]);
            return nil;
        }
    }
    return uuid;
}
于 2013-11-26T09:25:37.597 に答える
0

完全ではありませんが、UDID に代わる最良かつ最も近いものの 1 つです (iOS 8.1 および Xcode 6.1 を使用する Swift で):

ランダムな UUID の生成

let strUUID: String = NSUUID().UUIDString

KeychainWrapperライブラリを使用します。

キーチェーンに文字列値を追加します。

let saveSuccessful: Bool = KeychainWrapper.setString("Some String", forKey: "myKey")

キーチェーンから文字列値を取得します。

let retrievedString: String? = KeychainWrapper.stringForKey("myKey")

キーチェーンから文字列値を削除します。

let removeSuccessful: Bool = KeychainWrapper.removeObjectForKey("myKey")

このソリューションはキーチェーンを使用するため、アプリをアンインストールして再インストールした後でも、キーチェーンに保存されたレコードは保持されます。この記録を削除する唯一の方法は、デバイスのすべてのコンテンツと設定をリセットすることです。そのため、この置換ソリューションは完全ではありませんが、Swift を使用して iOS 8.1 で UDID を置換する最良のソリューションの 1 つであることに変わりはありません。

于 2014-12-01T01:52:14.290 に答える
0

私もいくつかの問題を抱えていましたが、解決策は簡単です:

    // Get Bundle Info for Remote Registration (handy if you have more than one app)
    NSString *appName = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleDisplayName"];
    NSString *appVersion = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];


    // Get the users Device Model, Display Name, Unique ID, Token & Version Number
    UIDevice *dev = [UIDevice currentDevice];
    NSString *deviceUuid=[dev.identifierForVendor  UUIDString];

    NSString *deviceName = dev.name;
于 2014-04-18T19:39:26.763 に答える
-1

これらのライブラリを使用しないでください - libOmnitureAppMeasurement、Apple がサポートしなくなった uniqueIdentifier を使用します

于 2013-06-05T14:41:56.153 に答える
-2

ちょっとしたハック:

/**
 @method uniqueDeviceIdentifier
 @abstract A unique device identifier is a hash value composed from various hardware identifiers such
 as the device’s serial number. It is guaranteed to be unique for every device but cannot 
 be tied to a user account. [UIDevice Class Reference]
 @return An 1-way hashed identifier unique to this device.
 */
+ (NSString *)uniqueDeviceIdentifier {      
    NSString *systemId = nil;
    // We collect it as long as it is available along with a randomly generated ID.
    // This way, when this becomes unavailable we can map existing users so the
    // new vs returning counts do not break.
    if (([[[UIDevice currentDevice] systemVersion] floatValue] < 6.0f)) {
        SEL udidSelector = NSSelectorFromString(@"uniqueIdentifier");
        if ([[UIDevice currentDevice] respondsToSelector:udidSelector]) {
            systemId = [[UIDevice currentDevice] performSelector:udidSelector];
        }
    }
    else {
        systemId = [NSUUID UUID];
    }
    return systemId;
}
于 2013-05-17T08:55:04.703 に答える