UIDevice uniqueIdentifier เลิกใช้แล้ว - จะทำอย่างไร?


501

เพิ่งทราบว่าคุณสมบัติ UIDevice uniqueIdentifier นั้นเลิกใช้แล้วในiOS 5และไม่สามารถใช้งานได้ใน iOS 7 ขึ้นไป ดูเหมือนว่าจะไม่มีวิธีการหรือคุณสมบัติทางเลือกอื่น ๆ

แอพที่มีอยู่จำนวนมากของเราขึ้นอยู่กับคุณสมบัตินี้อย่างแน่นหนาเพื่อระบุอุปกรณ์เฉพาะ เราจะจัดการปัญหานี้ในอนาคตได้อย่างไร?

คำแนะนำจากเอกสารในปี 2554-2555คือ:

ข้อควรพิจารณาพิเศษ

อย่าใช้คุณสมบัติ uniqueIdentifier ในการสร้างตัวระบุเฉพาะสำหรับแอปของคุณคุณสามารถเรียกใช้CFUUIDCreateฟังก์ชันเพื่อสร้างUUIDและเขียนลงในฐานข้อมูลเริ่มต้นโดยใช้NSUserDefaultsคลาส

อย่างไรก็ตามค่านี้จะไม่เหมือนกันหากผู้ใช้ถอนการติดตั้งและติดตั้งแอปอีกครั้ง


1
สำหรับแอพที่ยังคงใช้งาน UniqueIdentifier อยู่ตอนนี้ iOS7 จะส่งคืน FFFFFFFF + identifierForVendor ซึ่งทำลายแอพการสมัครสมาชิกที่ไม่ได้รับการต่ออายุ
Fistman Rhythmic

หากโชคดีที่แอปของคุณใช้การแจ้งเตือนแบบกดคุณสามารถใช้โทเค็นที่ส่งกลับจากบริการพุชของแอปเปิ้ลซึ่งเป็นเอกลักษณ์ต่ออุปกรณ์เช่นกัน
Calin Chitu

@CalinChitu หากผู้ใช้ไม่ยอมรับการแจ้งเตือนแบบพุชคุณยังคงได้รับ pushID สำหรับผู้ใช้รายนั้นหรือไม่
Chase Roberts

คำตอบ:


272

UUID สร้างขึ้นโดยCFUUIDCreate เป็นที่ไม่ซ้ำกันถ้าถอนการติดตั้งการใช้งานและติดตั้งใหม่ app: คุณจะได้รับหนึ่งใหม่ทุกครั้ง

แต่คุณอาจต้องการให้มันไม่ซ้ำกันนั่นคือมันจะยังคงเหมือนเดิมเมื่อผู้ใช้ถอนการติดตั้งและติดตั้งแอปอีกครั้ง สิ่งนี้ต้องใช้ความพยายามเล็กน้อยเนื่องจากอุปกรณ์ต่อตัวระบุที่น่าเชื่อถือที่สุดน่าจะเป็นที่อยู่ MAC คุณสามารถสืบค้น MACและใช้เป็น UUID

แก้ไข:หนึ่งต้องค้นหา MAC ของอินเทอร์เฟซเดียวกันแน่นอนเสมอ en0ผมคิดว่าทางออกที่ดีที่สุดคือด้วย MAC แสดงอยู่เสมอแม้ว่าอินเทอร์เฟซจะไม่มี IP / ไม่ทำงาน

แก้ไข 2:ในฐานะที่ได้รับการชี้ให้เห็นโดยคนอื่น ๆ เป็นทางออกที่ต้องการตั้งแต่ iOS 6 - [UIDevice identifierForVendor] ในกรณีส่วนใหญ่คุณควรใช้แทนการแทนที่เป็นแบบเก่า-[UIDevice uniqueIdentifier](แต่ UUID ที่สร้างขึ้นเมื่อแอปเริ่มต้นในครั้งแรกคือสิ่งที่ Apple ต้องการให้คุณใช้)

แก้ไข 3:ดังนั้นจุดสำคัญนี้ไม่ได้หายไปในเสียงความคิดเห็น: ไม่ได้ใช้MACเป็น UUID สร้างกัญชาใช้ MAC แฮชนั้นจะสร้างผลลัพธ์เดียวกันทุกครั้งแม้กระทั่งการติดตั้งซ้ำและแอพ (ถ้าการแฮชทำในลักษณะเดียวกัน) อย่างไรก็ตามทุกวันนี้ (2013) สิ่งนี้ไม่จำเป็นอีกต่อไปยกเว้นถ้าคุณต้องการตัวระบุอุปกรณ์ "เสถียร" บน iOS <6.0

แก้ไข 4:ใน iOS 7 ตอนนี้ Apple จะส่งคืนค่าคงที่เสมอเมื่อทำการค้นหา MAC เพื่อขัดขวางMACโดยเฉพาะเพื่อเป็นพื้นฐานสำหรับแบบแผนID ดังนั้นตอนนี้คุณควรใช้- [UIDevice identifierForVendor]หรือสร้าง UUID ต่อการติดตั้ง


8
ที่อยู่ mac ไม่เปลี่ยนแปลงขึ้นอยู่กับว่าผู้ใช้เชื่อมต่อผ่าน Wifi หรือไม่
Oliver Pearmain

1
@DarkDust: แต่เนื่องจากการเปลี่ยนแปลงอินเตอร์เฟซที่ใช้งานเมื่อคุณเปลี่ยนจาก wifi เป็นโมเด็มมือถือที่อยู่ MAC ของอินเตอร์เฟซที่ใช้งานควรเปลี่ยน; นอกเสียจากคุณจะเลือกอินเทอร์เฟซเฉพาะเพื่อรับ MAC
user102008

3
@Roger Nolan: โปรดอย่าแก้ไขคำตอบของผู้อื่นและเพิ่มเนื้อหาที่ดูเหมือนว่ามาจากผู้เขียนต้นฉบับ ขอบคุณ
DarkDust

2
@RogerNolan ตราบใดที่โพสต์ไม่ใช่คำตอบของชุมชนการแก้ไขก็เพื่อแก้ไขข้อผิดพลาดและสิ่งต่าง ๆ ไม่ใช่เพื่อเพิ่มสิ่งใหม่ มีเหตุผลที่คุณได้รับสิทธิพิเศษ ลองนึกภาพฉันจะแก้ไขคำตอบของคุณและเขียน BS บางคนจะคิดว่าคุณจะได้เขียนว่า ฉันสงสัยว่าคุณต้องการ :-) แต่คุณไม่ได้รับแจ้งว่ามีการแก้ไขเกิดขึ้นฉันค้นพบโดยบังเอิญเท่านั้น
DarkDust

3
ตอนนี้ Apple ปฏิเสธแอปที่ใช้ MAC ที่แฮช
Idan

91

คุณสามารถใช้ทางเลือกแทน Apple UDIDได้แล้ว Kind guy gekitz เขียนหมวดหมู่UIDeviceซึ่งจะสร้างประเภทของUDIDอุปกรณ์ตามที่อยู่ mac-address และตัวระบุบันเดิล

คุณสามารถค้นหารหัสในGitHub


3
การใช้งานนี้ไม่ซ้ำกัน (ที่อยู่ MAC) สำหรับอุปกรณ์ในการติดตั้งใหม่เช่น AppleIdIdId แต่ยังเคารพความเป็นส่วนตัวเป็นพิเศษสำหรับแอปพลิเคชัน (เช่นใช้ BundleId) ... ต้องมี imho ที่ Apple ควรรวมไว้ใน API ของมัน .. แทนการคัดค้านโดยไม่มีทางเลือกใด ๆ
Vincent Guerci

8
แม้ว่าจะใช้สิทธิ์การใช้งาน bsd แบบเก่ากับส่วนคำสั่งโฆษณา yuck
jbtule

8
สำหรับใครก็ตามที่หาโพสต์นี้ตอนนี้มีการเปลี่ยนแปลงใบอนุญาตตั้งแต่ความคิดเห็นข้างต้นโดย jbtule
James

1
ตามที่กล่าวไว้ในนี้กระทำคิดเห็นห้องสมุดตามที่เป็นโพสท่าเป็นปัญหาการรั่วไหลของความเป็นส่วนตัวที่ร้ายแรงและไม่ควรใช้:
Will

15
เริ่มต้นจาก iOS 7 ระบบจะส่งคืนค่าเสมอ02:00:00:00:00:00เมื่อคุณขอที่อยู่ MAC บนอุปกรณ์ใด ๆ ตรวจสอบที่นี่: developer.apple.com/library/prerelease/ios/releasenotes/General/…
Hejazi

61

จากลิงก์ที่เสนอโดย @moonlight ฉันได้ทำการทดสอบหลายครั้งและดูเหมือนว่าจะเป็นทางออกที่ดีที่สุด ในฐานะที่เป็น @DarkDust กล่าวว่าวิธีการไปเพื่อตรวจสอบen0ซึ่งมักจะใช้ได้
มี 2 ​​ตัวเลือก:
uniqueDeviceIdentifier(MD5 ของ MAC + CFBundleIdentifier)
และuniqueGlobalDeviceIdentifier(MD5 ของ MAC) สิ่งเหล่านี้จะส่งกลับค่าเดิมเสมอ
ด้านล่างการทดสอบที่ฉันทำ (ด้วยอุปกรณ์จริง):

#import "UIDevice+IdentifierAddition.h"

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

XXXX21f1f19edff198e2a2356bf4XXXX - (WIFI) UDID
XXXX7dc3c577446a2bcbd77935bdXXXXX - (WIFI) GlobalAppUDID

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

XXXX21f1f19edff198e2a2356bf4XXXX - (GPRS) UDID
XXXX7dc3c577446a2bcbd77935bdXXXXX - (GPRS) GlobalAppUDID

XXXX21f1f19edff198e2a2356bf4XXXX - (โหมด AirPlane) UDID
XXXX7dc3c577446a2bcbd77935bdXXXXX - (โหมดเครื่องบินเครื่องบิน) GlobalAppUDID

XXXX21f1f19edff198e2a2356bf4XXXX - (Wi-Fi) หลังจากลบและติดตั้งแอปใหม่ XXXX7dc3c577446a2bcbd77935bdXXXXX (Wi-Fi) หลังจากลบและติดตั้งแอป

หวังว่ามันจะมีประโยชน์

แก้ไข:
ตามที่คนอื่น ๆ ชี้ให้เห็นวิธีแก้ปัญหาใน iOS 7 นี้ไม่มีประโยชน์อีกต่อไปเนื่องจากuniqueIdentifierไม่สามารถใช้งานได้อีกต่อไปและการค้นหาที่อยู่ MAC จะส่งคืนเสมอ 02: 00: 00: 00: 00: 00


13
สิ่งนี้จะไม่ทำงานบน iOS7, Apple กำจัดการใช้ที่อยู่ MAC
Sarim Sidd

@SarimSidd สำหรับข้อมูลตอนนี้เกี่ยวกับ iOS 7 อยู่ภายใต้ NDA เราไม่สามารถพูดคุยที่นี่
Mat

57

ลองดู,

เราสามารถใช้พวงกุญแจแทนNSUserDefaultsระดับในการจัดเก็บที่สร้างขึ้นโดยUUIDCFUUIDCreate

ด้วยวิธีนี้เราสามารถหลีกเลี่ยงการUUIDพักผ่อนหย่อนใจด้วยการติดตั้งใหม่และรับเหมือนกันเสมอUUIDสำหรับแอปพลิเคชันเดียวกันแม้ผู้ใช้จะถอนการติดตั้งและติดตั้งใหม่อีกครั้ง

UUID จะสร้างขึ้นใหม่เมื่อผู้ใช้รีเซ็ตอุปกรณ์

ฉันลองใช้วิธีนี้กับSFHFKeychainUtilsและใช้งานได้อย่างมีเสน่ห์


33
วิธีนี้เป็นการแทนที่ที่แข็งแกร่งสำหรับ UDID นอกจากนี้ยังมีประโยชน์เพิ่มเติมของการสร้างตัวระบุตามรูปแบบอุปกรณ์ (เช่นหากอุปกรณ์เปลี่ยนเจ้าของ) อย่างไรก็ตามสิ่งสำคัญคือต้องทราบว่าสามารถกู้คืนพวงกุญแจไปยังอุปกรณ์อื่นได้หากผู้ใช้เข้ารหัสข้อมูลสำรองของพวกเขา สิ่งนี้อาจส่งผลให้เกิดสถานการณ์ที่อุปกรณ์หลายเครื่องใช้ UUID ร่วมกัน kSecAttrAccessibleAlwaysThisDeviceOnlyเพื่อหลีกเลี่ยงนี้ตั้งการเข้าถึงของรายการพวงกุญแจของคุณไป สิ่งนี้จะช่วยให้มั่นใจได้ว่า UUID ของคุณจะไม่ย้ายไปยังอุปกรณ์อื่น ในการเข้าถึง UUID ของคุณจากแอพอื่น ๆ ให้ใช้kSecAttrAccessGroupกุญแจ
Jeevan Takhar

คุณควรจะใช้ตำแหน่งใดในการเก็บ UUID ไว้ในพวงกุญแจ
แปลที่หายไป

ขออภัย! ลิงก์เสีย
COVID19

48

สร้าง UUID ของคุณเองจากนั้นเก็บไว้ใน Keychain ดังนั้นมันจะยังคงอยู่แม้ว่าแอพของคุณจะถูกถอนการติดตั้ง ในหลายกรณียังคงอยู่แม้ว่าผู้ใช้จะย้ายข้อมูลระหว่างอุปกรณ์ (เช่นการสำรองข้อมูลเต็มรูปแบบและเรียกคืนไปยังอุปกรณ์อื่น)

อย่างมีประสิทธิภาพมันจะกลายเป็นตัวระบุผู้ใช้ที่ไม่ซ้ำกันเท่าที่คุณกังวล (ดียิ่งกว่าตัวระบุอุปกรณ์ )

ตัวอย่าง:

ฉันกำหนดวิธีการที่กำหนดเองสำหรับการสร้างUUIDเป็น:

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

จากนั้นคุณสามารถเก็บไว้ในKEYCHAINการเปิดตัวแอปแรกของคุณ เพื่อให้หลังจากเปิดตัวครั้งแรกเราสามารถใช้มันจากพวงกุญแจไม่จำเป็นต้องงอกใหม่ เหตุผลหลักสำหรับการใช้ Keychain to store คือ: เมื่อคุณตั้งค่าเป็นUUIDKeychain จะยังคงอยู่แม้ว่าผู้ใช้จะถอนการติดตั้งแอพอย่างสมบูรณ์แล้วติดตั้งอีกครั้ง . ดังนั้นนี่คือวิธีการเก็บถาวรซึ่งหมายความว่ากุญแจจะไม่ซ้ำกันตลอดทาง

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

เมื่อเปิดตัว applictaion รวมถึงรหัสต่อไปนี้:

 // 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"];

เนื่องจากตัวระบุ ForVendor ทำงานไม่สมบูรณ์ ในบางกรณีสามารถส่งคืนศูนย์หรือ 0x0 วิธีนี้ดูเหมือนว่าจะทำงานได้อย่างสมบูรณ์แบบ
CReaTuS

3
ทุกคนที่ตรวจสอบความถูกต้องทำงานบน iOS7 หลังจากถอนการติดตั้ง / ติดตั้งรอบใหม่ + ส่งแอปเปิ้ลที่ได้รับการยืนยันแล้วหรือไม่
mindbomb

ฉันเริ่มใช้โซลูชันนี้ การทดสอบบนอุปกรณ์ 2 ชิ้น (สร้างใหม่ติดตั้งใหม่ปิดอุปกรณ์) แสดงให้ฉันเห็นว่า ID เหมือนกัน iOS 10.3
deko

16

บางทีคุณสามารถใช้:

[UIDevice currentDevice].identifierForVendor.UUIDString

เอกสารของ Apple อธิบาย identifierForVender ดังนี้:

มูลค่าของคุณสมบัตินี้จะเหมือนกันสำหรับแอพที่มาจากผู้ขายรายเดียวกันที่ทำงานบนอุปกรณ์เดียวกัน ค่าที่แตกต่างกันจะถูกส่งคืนสำหรับแอพในอุปกรณ์เดียวกันที่มาจากผู้จำหน่ายที่ต่างกันและสำหรับแอพในอุปกรณ์ต่าง ๆ โดยไม่คำนึงถึงผู้ขาย


อยากรู้ว่าทำไมไม่มีใครนำเรื่องนี้มาจนกระทั่งเมื่อเร็ว ๆ นี้ ... และตอนนี้ฉันเห็นว่ามันใหม่กับ iOS 6
James Boutcher

1
หากผู้ใช้อัพเดต iOS และ / หรือติดตั้ง iOS ใหม่ค่าของ identifierForVendor จะเปลี่ยนหรือยังคงเหมือนเดิมหรือไม่?
Sunil Zalavadiya

1
หลังจากลบแอพทั้งหมดจากผู้ขายรายเดียวกันค่านี้จะเปลี่ยนไป
Mitesh Khatri

14

คุณอาจต้องการที่จะต้องพิจารณาใช้ซึ่งเป็นดรอปแทนสำหรับเลิกOpenUDIDUDID

โดยทั่วไปเพื่อให้ตรงกับUDIDคุณสมบัติที่จำเป็นต่อไปนี้:

  1. ไม่ซ้ำกันหรือไม่ซ้ำกัน (การชนกันของความน่าจะเป็นต่ำน่าจะยอมรับได้มาก)
  2. การคงอยู่ในการรีบูตการคืนค่าการถอนการติดตั้ง
  3. พร้อมใช้งานในแอพของผู้จำหน่ายต่าง ๆ (มีประโยชน์ในการรับผู้ใช้ผ่านเครือข่าย CPI) -

OpenUDID ปฏิบัติตามข้างต้นและยังมีกลไกการเลือกไม่ใช้ในตัวเพื่อการพิจารณาในภายหลัง

ตรวจสอบhttp://OpenUDID.org โดยชี้ไปที่ GitHub ที่เกี่ยวข้อง หวังว่านี่จะช่วยได้!

ในฐานะที่เป็นข้อความด้านข้างฉันจะอายจากที่อยู่ MAC อื่น ๆ ในขณะที่ที่อยู่ MAC นั้นดูเหมือนเป็นโซลูชันที่ดึงดูดและเป็นสากล แต่ให้แน่ใจว่าผลไม้แขวนลอยต่ำนี้เป็นพิษ ที่อยู่ MAC นั้นอ่อนไหวมากและ Apple อาจเลิกการเข้าถึงที่นี่ได้ดีก่อนที่คุณจะพูดว่า "ส่งแอปนี้" ... ที่อยู่เครือข่าย MAC ใช้ในการตรวจสอบความถูกต้องของอุปกรณ์ส่วนตัวบนเครือข่ายส่วนตัวหรือ WLAN เครือข่าย (VPN) .. มันมีความไวมากกว่า UDID เดิม!


ฉันอยากรู้จริงๆว่ามันทำงานอย่างไร โค้ดถูกเขียนใน Objective-C แต่ไม่มีวิธีแก้ปัญหาที่ดีอื่นที่เหมาะสมกับข้อกำหนดข้างต้นดังนั้นอะไรที่ทำให้กรอบนี้แตกต่างกัน? วิธีแก้ปัญหาที่ใช้เฟรมเวิร์กนี้ควรโพสต์เป็นคำตอบที่แนะนำได้ที่นี่ ...
jake_hetfield

ฉันเห็นด้วย - ที่อยู่ MAC สามารถกำหนดค่าด้วยตนเองได้เช่นกัน ("โคลน") แม้ว่าส่วนใหญ่จะไม่น่าจะเป็นไปได้ ฉันต้องประท้วง D ใน UDID นี่ไม่ใช่ ID อุปกรณ์มันเป็น UUID (ตัวระบุที่ไม่ซ้ำแบบสากล) รหัสอุปกรณ์ถูกประทับโดย Apple จากโรงงานในแต่ละอุปกรณ์ใน ROM
Jay Imerman

ทางออกที่ดีที่สุดสำหรับ iOS7 รวมถึงสิ่งที่จำเป็นในการระบุอุปกรณ์โดยเฉพาะ
vishal dharankar

1
OpenUDID เลิกใช้แล้วและไม่แนะนำให้ใช้
mkll

11

ฉันแน่ใจว่าแอปเปิ้ลสร้างความรำคาญให้กับผู้คนมากมายจากการเปลี่ยนแปลงนี้ ฉันพัฒนาแอพทำบัญชีสำหรับ iOS และมีบริการออนไลน์เพื่อซิงค์การเปลี่ยนแปลงที่ทำกับอุปกรณ์ต่าง ๆ บริการรักษาฐานข้อมูลของอุปกรณ์ทั้งหมดและการเปลี่ยนแปลงที่จำเป็นต้องเผยแพร่ไปยังอุปกรณ์เหล่านั้น ดังนั้นจึงเป็นสิ่งสำคัญที่จะต้องรู้ว่าอุปกรณ์ใดที่ ฉันกำลังติดตามอุปกรณ์โดยใช้ UIDevice uniqueIdentifier และสิ่งที่คุ้มค่านี่คือความคิดของฉัน

  • สร้าง UUID และเก็บไว้ในค่าเริ่มต้นของผู้ใช้หรือไม่ ไม่ดีเพราะสิ่งนี้ไม่คงอยู่เมื่อผู้ใช้ลบแอป หากพวกเขาติดตั้งอีกครั้งในภายหลัง Online Service ไม่ควรสร้างระเบียนอุปกรณ์ใหม่ซึ่งจะทำให้สิ้นเปลืองทรัพยากรบนเซิร์ฟเวอร์และให้รายการอุปกรณ์ที่มีหนึ่งหรือสองครั้งเดียวกัน ผู้ใช้จะเห็นรายการ "iPhone ของ Bob" มากกว่าหนึ่งรายการหากพวกเขาติดตั้งแอปอีกครั้ง

  • สร้าง UUID และเก็บไว้ในพวงกุญแจ? นี่เป็นแผนของฉันเนื่องจากมันยังคงอยู่แม้จะถอนการติดตั้งแอพ แต่เมื่อกู้คืนข้อมูลสำรอง iTunes ไปยังอุปกรณ์ iOS ใหม่พวงกุญแจจะถูกโอนหากการสำรองข้อมูลถูกเข้ารหัส สิ่งนี้อาจนำไปสู่อุปกรณ์สองเครื่องที่มีรหัสอุปกรณ์เดียวกันหากอุปกรณ์ทั้งเก่าและใหม่พร้อมให้บริการ ควรแสดงรายการเหล่านี้เป็นสองอุปกรณ์ใน Online Service แม้ว่าชื่ออุปกรณ์จะเหมือนกัน

  • สร้างที่อยู่ MAC และรหัสกลุ่มแฮชหรือไม่ ดูเหมือนว่าทางออกที่ดีที่สุดสำหรับสิ่งที่ฉันต้องการ ด้วยการแฮชกับรหัสบันเดิลรหัสอุปกรณ์ที่สร้างจะไม่สามารถเปิดใช้งานอุปกรณ์ที่จะถูกติดตามข้ามแอพและฉันจะได้รับ ID ที่ไม่ซ้ำสำหรับแอพ + อุปกรณ์

เป็นที่น่าสนใจที่จะทราบว่าเอกสารของ Apple หมายถึงการตรวจสอบใบเสร็จรับเงินของMac App Store โดยการคำนวณแฮชของที่อยู่ MAC ของระบบรวมถึงรหัสบันเดิลและเวอร์ชัน ดังนั้นสิ่งนี้จึงเป็นนโยบายที่อนุญาตได้ไม่ว่าจะผ่านการตรวจสอบแอพฉันยังไม่รู้


10
kSecAttrAccessibleAlwaysThisDeviceOnlyเพื่อหลีกเลี่ยงสถานการณ์ที่อธิบายไว้ในจุดที่สองของคุณตั้งค่าการเข้าถึงของรายการพวงกุญแจของคุณไป สิ่งนี้จะช่วยให้มั่นใจได้ว่า UUID ของคุณจะไม่กู้คืนไปยังอุปกรณ์อื่นแม้ว่าการสำรองข้อมูลจะถูกเข้ารหัส
Jeevan Takhar

นี่เป็นพฤติกรรมที่ฉันเคยเห็นมาหลายครั้งแล้ว ตัวอย่างเช่นฉันลงทะเบียน iPhone ของฉันกับ Google Sync จากนั้นฉันได้ iPhone ใหม่ลงทะเบียนและ voila - ตอนนี้ฉันมี iPhone 2 เครื่องที่ระบุไว้ในการตั้งค่าการซิงค์ของฉัน
Jay Imerman

11

ดูเหมือนว่าสำหรับ iOS 6, แอปเปิ้ลแนะนำคุณใช้ชั้น NSUUID

จากข้อความตอนนี้ในUIDevice docs สำหรับuniqueIdentifierคุณสมบัติ:

เลิกใช้ใน iOS 5.0 ใช้คุณสมบัติ identifierForVendor ของคลาสนี้หรือคุณสมบัติ AdvertisingIdentifier ของคลาส ASIdentifierManager แทนตามความเหมาะสมหรือใช้วิธี UUID ของคลาส NSUUID เพื่อสร้าง UUID และเขียนลงในฐานข้อมูลเริ่มต้นของผู้ใช้


10

อาจช่วย: ใช้รหัสด้านล่างมันจะไม่ซ้ำกันยกเว้นคุณลบ (รูปแบบ) อุปกรณ์ของคุณ

UIDevice *myDevice=[UIDevice currentDevice];
NSString *UUID = [[myDevice identifierForVendor] UUIDString];

1
ฉันใช้รหัสนี้ แต่เมื่อฉันลบแอพและติดตั้งอีกครั้งฉันได้รับ Id ใหม่
Durgaprasad

1
นี่เป็นวิธีง่ายๆหากคุณไม่ต้องการวิธีที่มีประสิทธิภาพ ฉันใช้มันในแอพของฉันตอนนี้
รูเบนแอล

@Durgaprasad: มันจะเปลี่ยนเสมอเพราะมันขึ้นอยู่กับผู้ขาย ตัวอย่างเช่น: 1. หากคุณติดตั้งแอพที่มี bundleidenedifier: com.abcd.com => มันจะเปลี่ยนไป 2. หากคุณติดตั้งแอพสองตัวพร้อมกับ bundleidenedifier: com.abcd.com => แล้วมันจะไม่เปลี่ยน (เก็บแอปใดแอปหนึ่งระหว่างนี้)
Ashvin Ajadiya

7

ฉันขอแนะนำให้เปลี่ยนจากuniqueIdentifierเป็นไลบรารีโอเพ่นซอร์ส (2 หมวดง่าย ๆ จริง ๆ ) ที่ใช้ที่อยู่ MAC ของอุปกรณ์พร้อมกับ App Bundle Identifier เพื่อสร้าง ID เฉพาะในแอปพลิเคชันของคุณที่สามารถใช้แทน UDID ได้

โปรดทราบว่าหมายเลขนี้จะแตกต่างจาก UDID ทุกแอพ

คุณเพียงแค่ต้องนำเข้าสิ่งที่รวมอยู่NSStringและUIDeviceหมวดหมู่แล้วโทรออกโดย[[UIDevice currentDevice] uniqueDeviceIdentifier]:

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

คุณสามารถหาได้จาก Github ที่นี่:

UIDevice พร้อม UniqueIdentifier สำหรับ iOS 5


นี่คือหมวดหมู่ (เพียงไฟล์. 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

3
เริ่มต้นใน iOS 7, Apple จะคืนค่าคงที่สำหรับที่อยู่ MAC มันทำให้รู้สึกที่สมบูรณ์แบบ ที่อยู่ MAC นั้นอ่อนไหว
Roberto


4

ที่อยู่ MAC สามารถปลอมแปลงซึ่งทำให้วิธีการดังกล่าวไร้ประโยชน์สำหรับการผูกเนื้อหากับผู้ใช้ที่เฉพาะเจาะจงหรือการใช้งานคุณลักษณะด้านความปลอดภัยเช่นบัญชีดำ

หลังจากการวิจัยเพิ่มเติมดูเหมือนว่าเราจะถูกทิ้งไว้โดยไม่มีทางเลือกที่เหมาะสม ณ ตอนนี้ ฉันหวังเป็นอย่างยิ่งว่า Apple จะพิจารณาการตัดสินใจของพวกเขาอีกครั้ง

อาจเป็นความคิดที่ดีที่จะส่งอีเมลถึง Apple เกี่ยวกับหัวข้อนี้และ / หรือส่งคำขอข้อผิดพลาด / คุณสมบัติเกี่ยวกับเรื่องนี้


13
จุดที่ถูกต้อง แต่ฉันเชื่อว่า UUID สามารถปลอมแปลง / swizzled บนโทรศัพท์ที่ถูกคุมขังดังนั้นเทคนิคในทางเทคนิค [UIDevice uniqueIdentifier] ที่มีอยู่นั้นมีข้อบกพร่องเช่นกัน
Oliver Pearmain

3
คุณสามารถสร้างตัวระบุบนเซิร์ฟเวอร์และบันทึกบนอุปกรณ์ได้ตลอดเวลา นั่นเป็นวิธีที่แอปพลิเคชันส่วนใหญ่ทำ ฉันไม่เข้าใจว่าทำไมโปรแกรมเมอร์ iOS จึงต้องการบางสิ่งที่พิเศษ
Sulthan

1
@Sulthan ไม่ทำงานบน iOS เพราะหากคุณถอนการติดตั้งแอปข้อมูลทั้งหมดจะหายไปดังนั้นจึงไม่มีวิธีรับประกันตัวระบุอุปกรณ์ที่ไม่ซ้ำแบบนั้น
lkraider

4
ไม่ใช่ถ้าคุณบันทึกลงในพวงกุญแจ อย่างไรก็ตามฉันไม่เคยเห็นแอพที่มีปัญหา หากแอพและข้อมูลถูกลบคุณไม่จำเป็นต้องใช้ตัวระบุอุปกรณ์เดียวกัน หากคุณต้องการระบุผู้ใช้ให้ขออีเมลจากเขา
Sulthan

Apple ห้ามการเข้าถึงที่อยู่ MAC โดย Apple ใน iOS รุ่นใหม่
ตอบ

4

UIDevice identifierForVendor เปิดตัวใน iOS 6 จะใช้งานได้ตามวัตถุประสงค์ของคุณ

identifierForVendorเป็นสตริงตัวอักษรผสมตัวเลขที่ระบุอุปกรณ์ให้กับผู้จำหน่ายแอปโดยไม่ซ้ำกัน (อ่านเท่านั้น)

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

มูลค่าของคุณสมบัตินี้จะเหมือนกันสำหรับแอพที่มาจากผู้ขายรายเดียวกันที่ทำงานบนอุปกรณ์เดียวกัน ค่าที่แตกต่างกันจะถูกส่งคืนสำหรับแอพในอุปกรณ์เดียวกันที่มาจากผู้จำหน่ายที่ต่างกันและสำหรับแอพในอุปกรณ์ที่แตกต่างกันโดยคำนึงถึงผู้ขาย

พร้อมใช้งานใน iOS 6.0 และใหม่กว่าและประกาศใน UIDevice.h

สำหรับ iOS 5 ให้อ้างอิงลิงก์นี้UIDevice-with-UniqueIdentifier-for-iOS-5


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;

}


3

รหัสต่อไปนี้ช่วยในการรับ UDID:

        udid = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
        NSLog(@"UDID : %@", udid);

3

นี่คือรหัสที่ฉันใช้เพื่อรับ ID สำหรับทั้ง iOS 5 และ iOS 6, 7:

- (NSString *) advertisingIdentifier
{
    if (!NSClassFromString(@"ASIdentifierManager")) {
        SEL selector = NSSelectorFromString(@"uniqueIdentifier");
        if ([[UIDevice currentDevice] respondsToSelector:selector]) {
            return [[UIDevice currentDevice] performSelector:selector];
        }
    }
    return [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
}

คุณทำอย่างไรกับคำเตือนของคอมไพเลอร์PerformSelector may cause a leak because its selector is unknown?
Basil Bourque

คุณไม่สามารถใช้การโฆษณาตัวระบุสำหรับจุดประสงค์นี้ได้อีกเนื่องจาก Apple จะปฏิเสธ ข้อมูลเพิ่มเติม: techcrunch.com/2014/02/03/…
codeplasma


2

iOS 11 ได้เปิดตัวกรอบ DeviceCheck มันมีโซลูชั่นที่ป้องกันการแตกหักเต็มรูปแบบสำหรับการระบุอุปกรณ์ที่ไม่ซ้ำกัน


1

วิธีการทำงานเพื่อรับ UDID:

  1. เปิดเว็บเซิร์ฟเวอร์ภายในแอพด้วยสองหน้า: หน้าหนึ่งควรกลับมาที่โปรไฟล์การกำหนดค่า MobileConfiguration ที่สร้างขึ้นมาเป็นพิเศษและอีกหน้าควรรวบรวม UDID ข้อมูลเพิ่มเติมที่นี่ , ที่นี่และที่นี่
  2. คุณเปิดหน้าแรกใน Mobile Safari จากภายในแอพและจะนำคุณไปยัง Settings.app ที่ขอให้ติดตั้งโปรไฟล์กำหนดค่า หลังจากที่คุณติดตั้งโปรไฟล์ UDID จะถูกส่งไปยังหน้าเว็บที่สองและคุณสามารถเข้าถึงได้จากภายในแอพ (Settings.app มีสิทธิ์ที่จำเป็นทั้งหมดและกฎ sandbox ที่แตกต่างกัน)

ตัวอย่างการใช้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ด้วย


1

สำหรับ Swift 3.0 โปรดใช้รหัสด้านล่าง

let deviceIdentifier: String = (UIDevice.current.identifierForVendor?.uuidString)!
NSLog("output is : %@", deviceIdentifier)

1
iOS 11 ได้เปิดตัวกรอบ DeviceCheck มันมีโซลูชั่นที่ป้องกันการกระแทกเต็มรูปแบบสำหรับการระบุอุปกรณ์ที่ไม่ซ้ำกัน
Santosh Botre

1

คุณสามารถใช้ได้

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

ซึ่งมีเอกลักษณ์สำหรับอุปกรณ์ในทุกแอพพลิเคชั่น


1

Apple ได้เพิ่มเฟรมเวิร์กใหม่ใน iOS 11 ชื่อ DeviceCheck ซึ่งจะช่วยให้คุณได้ตัวระบุที่ไม่ซ้ำกันได้ง่ายมาก อ่านข้อมูลเพิ่มเติมในแบบฟอร์มนี้ https://medium.com/@santoshbotre01/unique-identifier-for-the-ios-devices-590bb778290d


แต่มันต้องการการเชื่อมต่ออินเทอร์เน็ตใช่ไหม?
Nik Kov

ใช่มันต้องการการเชื่อมต่ออินเทอร์เน็ต
Santosh Botre

0

หากใครบางคนสะดุดกับคำถามนี้เมื่อค้นหาทางเลือก ฉันได้ปฏิบัติตามวิธีการนี้ในIDManagerชั้นเรียนนี่เป็นคอลเล็กชันจากโซลูชันที่แตกต่างกัน KeyChainUtil เป็นเสื้อคลุมที่อ่านจากพวงกุญแจ นอกจากนี้คุณยังสามารถใช้hashed MAC addressเป็นรหัสเฉพาะได้

/*  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;
}

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;
}

0

เราสามารถใช้identifierForVendorสำหรับ ios7

-(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.

คุณแน่ใจไหม ? เราสามารถใช้ identifierForVendor สำหรับ ios7 ได้หรือไม่?
Avis

0

Apple ได้ซ่อน UDID จาก API สาธารณะทั้งหมดเริ่มต้นด้วย iOS 7 UDID ใด ๆ ที่ขึ้นต้นด้วย FFFF คือ ID ปลอม ไม่สามารถใช้แอป "ส่ง UDID" ที่ทำงานก่อนหน้านี้เพื่อรวบรวม UDID สำหรับอุปกรณ์ทดสอบอีกต่อไป (ถอนหายใจ)

UDID จะปรากฏขึ้นเมื่ออุปกรณ์เชื่อมต่อกับ XCode (ในออแกไนเซอร์) และเมื่ออุปกรณ์นั้นเชื่อมต่อกับ iTunes (แม้ว่าคุณจะต้องคลิกที่ 'หมายเลขซีเรียล' เพื่อให้ Identifier แสดง

หากคุณต้องการรับ UDID สำหรับอุปกรณ์เพื่อเพิ่มไปยังโปรไฟล์การจัดเตรียมและไม่สามารถทำได้ด้วยตัวคุณเองใน XCode คุณจะต้องดำเนินการตามขั้นตอนเหล่านี้เพื่อคัดลอก / วางจาก iTunes

มีวิธีตั้งแต่ (รุ่น iOS 7) เพื่อรับ UDID โดยไม่ต้องใช้ iTunes บน PC / Mac?


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;

0

ไม่สมบูรณ์ แต่เป็นหนึ่งในตัวเลือกที่ดีที่สุดและใกล้เคียงที่สุดกับ UDID (ใน 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")

วิธีการแก้ปัญหานี้ใช้พวงกุญแจดังนั้นบันทึกที่เก็บไว้ในพวงกุญแจจะยังคงอยู่แม้หลังจากถอนการติดตั้งแอปและติดตั้งใหม่ วิธีเดียวในการลบบันทึกนี้คือการรีเซ็ตเนื้อหาและการตั้งค่าทั้งหมดของอุปกรณ์ นั่นคือเหตุผลที่ฉันกล่าวว่าโซลูชันการทดแทนนี้ไม่สมบูรณ์แบบ แต่ยังคงเป็นหนึ่งในโซลูชันที่ดีที่สุดสำหรับการแทนที่ UDID บน iOS 8.1 โดยใช้ Swift


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.