UIDeviceのuniqueIdentifierプロパティは廃止予定 iniOS 5であり、iOS 7以降では使用できません。他の方法や特性は利用可能ではないか、または間もなく登場するようです。
既存のアプリの多くは、特定のデバイスを一意に識別するためにこのプロパティに強く依存しています。今後この問題にどう対処するのでしょうか。
特別な考慮事項
UniqueIdentifierプロパティを使用しないでください。アプリに固有の一意の識別子を作成するには、
CFUUIDCreate
関数を呼び出してUUID
を作成し、NSUserDefaults
クラスを使用してそれをデフォルトのデータベースに書き込むことができます。
ただし、ユーザーがアプリをアンインストールして再インストールした場合、この値は同じにはなりません。
CFUUIDCreate
によって作成されたUUIDは、ユーザーがアプリをアンインストールして再インストールするとuniqueになります。毎回新しいものが表示されます。
しかし、あなたはそれがではなく一意であることを望むかもしれません。 e。ユーザーがアプリをアンインストールして再インストールしても、同じままになります。最も信頼性の高いデバイスごとの識別子はMACアドレスであると思われるため、これには少し手間がかかります。あなたは MACに問い合わせ そしてそれをUUIDとして使うことができます。
編集:もちろん、常に同じインタフェースのMACに問い合わせる必要があります。最善の策はen0
です。インターフェイスにIPがない場合でも、MACは常に存在します。
編集2:他の人が指摘したように、iOS 6以降の推奨される解決法は - [UIDevice identifierForVendor] ほとんどの場合、古い-[UIDevice uniqueIdentifier]
の代わりにドロップインとして使用できるはずです(ただし、アプリの初回起動時に作成されるUUIDは、Appleが使用したいと思うものです)。
編集3:だから、この主要な点はコメントのノイズに迷うことはありません:UUIDとしてMACを使わないでください。MACを使用したハッシュ。そのハッシュは、再インストールやアプリがあっても常に同じ結果を常に生成します(ハッシュが同じ方法で行われる場合)。とにかく、最近(2013年)、iOS <6.0で "安定した"デバイス識別子が必要な場合を除いて、これはもう必要ありません。
編集4:iOS 7では、MACをIDスキームのベースとして具体的に阻止するためにMACを照会するときに、Appleは常に固定値を返すようになりました。ですから、 - [UIDevice identifierForVendor] を使用するか、インストールごとのUUIDを作成する必要があります。
あなたはすでにApple UDID
のためにあなたの代わりを使うことができます。親切なgekitzがUIDevice
にcategoryを書きました。これはデバイスのmac-addressとバンドル識別子に基づいてある種のUDID
を生成します。
コードは github にあります。
@moonlightによって提案されたリンクに基づいて、私はいくつかのテストをしました、そしてそれは最良の解決策のようです。 @DarkDustが言っているように、このメソッドはen0
をチェックします。これは常に利用可能です。
2つの選択肢があります。uniqueDeviceIdentifier
(MAC + CFBundleIdentifierのMD5)
とuniqueGlobalDeviceIdentifier
(MACのMD5)では、これらは常に同じ値を返します。
(実際のデバイスで)行ったテストの下に、
#import "UIDevice+IdentifierAddition.h"
NSLog(@"%@",[[UIDevice currentDevice] uniqueDeviceIdentifier]);
NSLog(@"%@",[[UIDevice currentDevice] uniqueGlobalDeviceIdentifier]);
XXXX21f1f19edff198e2a2356bf4XXXX - (WIFI)UDID
XXXX7dc3c577446a2bcbd77935bdXXXX - (WIFI)GlobalAppUDIDXXXX21f1f19edff198e2a2356bf4XXXX - (3G)UDID
XXXX7dc3c577446a2bcbd77935bdXXXX - (3G)GlobalAppUDIDXXXX21f1f19edff198e2a2356bf4XXXX - (GPRS)UDID
XXXX7dc3c577446a2bcbd77935bdXXXX - (GPRS)GlobalAppUDIDXXXX21f1f19edff198e2a2356bf4XXXX - (AirPlaneモード)UDID
XXXX7dc3c577446a2bcbd77935bdXXXX - (AirPlaneモード)GlobalAppUDIDXXXX21f1f19edff198e2a2356bf4XXXX - アプリを削除して再インストールした後のXXXX7dc3c577446a2bcbd77935bdXXXX(Wi-Fi)の削除
それが役に立つことを願っています。
編集:
他の人が指摘したように、uniqueIdentifier
はもう利用できず、MACアドレスの問い合わせは常に02:00:00:00:00:00を返すので、iOS 7のこのソリューションはもはや役に立ちません。
これをチェック
NSUserDefaults
によって作成されたUUID
を格納するために、CFUUIDCreate
クラスの代わりにKeychainを使用することができます。
こうすれば、再インストールによるUUID
の再作成を避け、ユーザーがアンインストールして再インストールしても、同じアプリケーションに対して常に同じUUID
を取得できます。
ユーザーがデバイスをリセットしたときにUUID
が再作成されます。
私は SFHFKeychainUtils を使ってこの方法を試しました、そしてそれは魅力のように働きます。
独自のUUIDを作成してからキーチェーンに保存します。したがって、アプリがアンインストールされても持続します。多くの場合、ユーザーがデバイス間を移動したとしてもそれは持続します(フルバックアップや他のデバイスへの復元など)。
あなたが関係している限り、事実上それはユニークなユーザー識別子になります。 (デバイス識別子よりも優れています)。
例:
私は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.mと.hファイルを sskeychain からダウンロードしてSSKeychain.mと.hファイルをプロジェクトにドラッグし、プロジェクトに "Security.framework"を追加します。 。後でUUIDを使用するには、単純に次のようにします。
NSString *retrieveuuid = [SSKeychain passwordForService:@"your app identifier" account:@"user"];
おそらくあなたは使用することができます:
[UIDevice currentDevice].identifierForVendor.UUIDString
アップルのドキュメントでは、identifierForVenderについて次のように説明されています。
このプロパティの値は、同じデバイス上で実行されている同じベンダからのアプリの場合と同じです。異なるベンダーから提供された同じデバイス上のアプリと、ベンダーに関係なく異なるデバイス上のアプリには異なる値が返されます。
廃止予定のOpenUDID
の代わりになるUDID
を使用することを検討してください。
基本的に、UDID
と一致させるには、以下の機能が必要です。
OpenUDID
は上記を満たし、後で検討するための組み込みのオプトアウトメカニズムさえ持っています。
チェック http://OpenUDID.org それは対応するGitHubを指しています。お役に立てれば!
ちなみに、私は他のMACアドレスの選択肢から敬遠するでしょう。 MACアドレスは魅力的で普遍的な解決策のように見えますが、この低い価値のある果物が中毒になっていることを確認してください。 MACアドレスは非常に機密性が高いため、Appleはこのアドレスへのアクセスを非推奨にする可能性があります。「このアプリを送信」... MACネットワークアドレスは、プライベートLAN(WLAN)またはその他のバーチャルプライベートの特定のデバイスを認証するために使用ネットワーク(VPN)。 ..以前のUDIDよりもさらに敏感です。
助けになるかもしれません:あなたがあなたの装置を消去(フォーマット)することを除いてそれは常にユニークになるコードの下の使用。
UIDevice *myDevice=[UIDevice currentDevice];
NSString *UUID = [[myDevice identifierForVendor] UUIDString];
私はAppleがこの変更に多くの人々を悩ませたと確信しています。私はiOS用の 簿記アプリ を開発し、さまざまなデバイスで行われた変更を同期するオンラインサービスを持っています。このサービスは、すべてのデバイスとそれらに伝播する必要がある変更のデータベースを維持します。したがって、どのデバイスがどれであるかを知ることが重要です。 UIDeviceのuniqueIdentifierを使ってデバイスを追跡していますが、その価値については、ここに私の考えがあります。
UUIDを生成してユーザーのデフォルトに保存するユーザーがアプリを削除したときにこれが持続しないので、ダメです。彼らが後でもう一度インストールした場合、オンラインサービスは新しいデバイスレコードを作成するべきではなく、それはサーバ上のリソースを浪費し、同じものを含むデバイスのリストを2回以上与えるでしょう。アプリを再インストールすると、複数の「Bob's iPhone」がリストに表示されます。
UUIDを生成してキーチェーンに保存しますか?アプリがアンインストールされても持続するので、これは私の計画でした。しかし、iTunesのバックアップを新しいiOSデバイスに復元するとき、バックアップが暗号化されていればキーチェーンが転送されます。古いデバイスと新しいデバイスの両方が稼働中の場合、これにより2つのデバイスに同じデバイスIDが含まれる可能性があります。デバイス名が同じであっても、これらはオンラインサービスで2つのデバイスとして表示されます。
MACアドレスとバンドルIDのハッシュを生成しますか?これは私が必要とするもののための最善の解決策のように見えます。バンドルIDでハッシュすることによって、生成されたデバイスIDはデバイスがアプリケーションを越えて追跡されることを可能にするつもりはありません、そして私はアプリ+デバイスの組み合わせのためのユニークなIDを取得します。
Apple自身のドキュメンテーションがシステムのMACアドレスとバンドルIDとバージョンのハッシュを計算することによって Mac App Storeの受信確認を検証することに言及していることに注目するのは興味深い。だから私はまだ知らないアプリレビューを通過するかどうか、これはポリシーで許容されるようです。
私はまた、uniqueIdentifier
から このオープンソースライブラリ (実際には2つの単純なカテゴリ)への切り替えを提案します。 UDIDの代わりとして使用できる、アプリケーション内で固有のIDを生成します。
UDIDとは異なり、この番号はアプリごとに異なります。
含まれているNSString
とUIDevice
のカテゴリーをインポートし、[[UIDevice currentDevice] uniqueDeviceIdentifier]
を呼び出すだけでいいのです。
#import "UIDevice+IdentifierAddition.h"
#import "NSString+MD5Addition.h"
NSString *iosFiveUDID = [[UIDevice currentDevice] uniqueDeviceIdentifier]
Githubにあります。
iOS 5用のUniqueIdentifierを持つUIDevice
カテゴリは次のとおりです(単に.mファイル - ヘッダーについてはgithubプロジェクトを確認してください)。
UIDevice + IdentifierAddition.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
あなたはこのコードから達成することができます: UIDevice-with-Unique-ID-for-iOS-5
MACアドレスが偽造される可能性があるため、コンテンツを特定のユーザーに結び付けたり、ブラックリストのようなセキュリティ機能を実装したりするのには、このようなアプローチは役に立ちません。
さらに調査を重ねた結果、現時点では適切な選択肢がないままになっているようです。私は、Appleが彼らの決定を再検討することを真剣に望んでいる。
おそらくこのトピックについてAppleに電子メールを送ったり、これに関するバグ/機能要求を提出したりするのは良い考えかもしれません。おそらく彼らは開発者にとっての全面的な影響についてさえ知らないのです。
iOS 6で導入されたUIDevice identifierForVendor
はあなたの目的のために働くでしょう。
identifierForVendor
は、アプリの製造元に対してデバイスを一意に識別する英数字の文字列です。 (読み取り専用)
@property(nonatomic, readonly, retain) NSUUID *identifierForVendor
このプロパティの値は、同じデバイス上で実行されている同じベンダからのアプリの場合と同じです。異なるベンダから提供された同じデバイス上のアプリと、ベンダーの観点から異なるデバイス上のアプリには異なる値が返されます。
IOS 6.0以降で利用可能で、UIDevice.h
で宣言されています
IOS 5の場合、このリンクを参照してください UIDevice-with-Unique-Identifier-for-iOS-5
上記の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;
}
次のコードはUDIDを取得するのに役立ちます。
udid = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
NSLog(@"UDID : %@", udid);
これは私がiOS 5とiOS 6、7の両方のIDを取得するために使っているコードです:
- (NSString *) advertisingIdentifier
{
if (!NSClassFromString(@"ASIdentifierManager")) {
SEL selector = NSSelectorFromString(@"uniqueIdentifier");
if ([[UIDevice currentDevice] respondsToSelector:selector]) {
return [[UIDevice currentDevice] performSelector:selector];
}
}
return [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
}
iOS 11はDeviceCheckフレームワークを導入しました。それはユニークにデバイスを識別するための完全な解決策を持っています。
AppleはiOS 11にDeviceCheckと呼ばれる新しいフレームワークを追加しました。これはあなたが非常に簡単にユニークな識別子を取得するのを助けます。このフォームの詳細情報を読んでください。 https://medium.com/@santoshbotre01/unique-identifier-for-the-ios-devices-590bb778290d
あなたが使用することができます
NSString *sID = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
これはすべてのアプリケーションでデバイスに固有のものです。
UDIDを取得するための実用的な方法:
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 にも署名してください。
Ios7にはidentifierForVendorを使用できます。
-(NSString*)uniqueIDForDevice
{
NSString* uniqueIdentifier = nil;
if( [UIDevice instancesRespondToSelector:@selector(identifierForVendor)] ) { // >=iOS 7
uniqueIdentifier = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
} else { //<=iOS6, Use UDID of Device
CFUUIDRef uuid = CFUUIDCreate(NULL);
//uniqueIdentifier = ( NSString*)CFUUIDCreateString(NULL, uuid);- for non- ARC
uniqueIdentifier = ( NSString*)CFBridgingRelease(CFUUIDCreateString(NULL, uuid));// for ARC
CFRelease(uuid);
}
}
return uniqueIdentifier;
}
- 重要な注意事項---
UDIDとidentifierForVendorは異なります。---
1.) On uninstalling and reinstalling the app identifierForVendor will change.
2.) The value of identifierForVendor remains the same for all the apps installed from the same vendor on the device.
3.) The value of identifierForVendor also changes for all the apps if any of the app (from same vendor) is reinstalled.
誰かがこの質問に出くわした場合、代替案を探すとき。私は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;
}
Swift 3.0の場合は、以下のコードを使用してください。
let deviceIdentifier: String = (UIDevice.current.identifierForVendor?.uuidString)!
NSLog("output is : %@", deviceIdentifier)
NSLog(@ "%@"、[[UIDevice currentDevice] identifierForVendor]);
Appleは、iOS 7以降、すべての公開APIからUDIDを隠しています。FFFFで始まるUDIDはすべて偽のIDです。以前は機能していた "Send UDID"アプリは、テストデバイス用のUDIDを収集するために使用できなくなりました。 (ため息!)
UDIDは、デバイスが(オーガナイザー内で)XCodeに接続されているとき、およびデバイスがiTunesに接続されているときに表示されます(ただし、識別子を表示するには「シリアル番号」をクリックする必要があります)。
プロビジョニングプロファイルに追加するデバイスのUDIDを取得する必要があり、XCodeで自分で作成できない場合は、iTunesからコピー/貼り付けする手順を実行する必要があります。
完璧ではありませんが、UDIDに代わる最も優れた代替手段の1つです(SwiftではiOS 8.1とXcode 6.1を使用)。
ランダムな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")
このソリューションではキーチェーンを使用するため、アプリをアンインストールして再インストールした後も、キーチェーンに保存されているレコードは保持されます。このレコードを削除する唯一の方法は、デバイスのすべての内容と設定をリセットすることです。そのため、この置換ソリューションは完全ではありませんが、iOS 8.1上でSwiftを使用したUDIDに代わる最良のソリューションの1つであり続けると私は述べました。
私もいくつかの問題を抱えていました、そして解決策は簡単です:
// 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;
+ (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;
}