標籤:style io ar os sp for 資料 on 問題
在做流量精靈的時候有這樣一個需求,帳戶預設需要取手機的imsi 資訊。這就有一個好處,即便使用者刪除我們的應用後從新下載,下次進入時他們還會以同樣的身份登陸,並且獲得原先紀錄。這樣不僅對於開發公司人員來說可以統計他是不是新使用者,而且對於使用者來說可以不用擔心之前記錄是否被刪除。(——我們的軟體是不需要註冊的,只要使用者登入就預設以imsi 為唯一標示來登記的)。
但是在iOS開發中,發現不同的系統如 iOS5、iOS6.0、以及iOS7,蘋果對它處理的態度是完全不同的。估計蘋果是對系統安全的考慮,6.0之後你若想取這些私密資訊是完全不可能的。所有的函數都已經被封鎖。 雖說作為一個開發來說很不願意看得此景,但另一方面作為一個喬布斯粉絲的我來說,完全可以理解蘋果的此舉。(反過來想一想,若你是一個使用者,而你手機中裝的每個軟體都可以在任意情況下擷取你的 私密資訊如:imsi,imei,手機號碼或者你的地理位置資訊。 那是多麼可怕的一件事情。——喬布斯當初不想開放iOS開發給世界就是為了不讓其他人汙染了他的商店,汙染使用者,汙染了系統)。
基於種種原因,我還是相對崇拜喬布斯的。
既然不能直接解決問題,那麼我們就嘗試著解決吧:這裡也嘗試過幾種吧
1、利用 NSUserDefaults 存取
- (NSString*)uniqueAppInstanceIdentifier
{
NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults];
static NSString* UUID_KEY = @"MPUUID";
NSString* app_uuid = [userDefaults stringForKey:UUID_KEY];
if (app_uuid == nil) {
CFUUIDRef uuidRef = CFUUIDCreate(kCFAllocatorDefault);
CFStringRef uuidString = CFUUIDCreateString(kCFAllocatorDefault, uuidRef);
app_uuid = [NSString stringWithString:(__bridge NSString*)uuidString];
[userDefaults setObject:app_uuid forKey:UUID_KEY];
[userDefaults synchronize];
CFRelease(uuidString);
CFRelease(uuidRef);
}
return app_uuid;
}
這種方法可以保證使用者不刪除軟體情況下的擷取同一個資料。因為NSUserDefaults 資料時儲存在 沙箱裡面的,會隨著軟體刪除而被清空。
2、利用 [[UIDevice currentDevice] identifierForVendor].UUIDString
此方法是官方6.0系統後推出的,指定唯一標示符號;不同軟體,不同機器,啟動並執行時候指都是不一樣的;也就是說可以滿足標識唯一性,前一段時間我都是用該方法來擷取資料的。 但是有個讓人糾結的問題:
a、大部分正版的手機在軟體卸載了,然後重新安裝的情況下還是會保持和原先儲存同一個值。
b、我一直以為這個方法沒問題的同時,在某一天,突然有個測試說:“我軟體卸載了,但是資料都清空了。。。。怎麼回事啊。”,後來發現 you right。有些越獄或者美版的手機 在卸載後都會重現擷取資料。------我的天哪。。。。
最方便的方案,就那麼被否決,還是有些失落!
也基於這些現在才有空重新來思考這個問題.... 裝置唯一標示符,並且這個標示符在軟體卸載重裝之後能和原先保持一致.....
3、KeyChian 方案
這個方案我開發之間就一直知道,也給新中大弄個過,只是自己完全不想弄。理由很簡單,一個工具軟體這樣弄有什麼意思呢?對於沒用的開發我向來都是很反感,很討厭的。 人們總想著完美的東西,卻壓根不知道自己所要的完美是什麼東西,總是說以後會有用的,總以為這樣就會讓自己變得成為一個思考全面的人。 可是在我認為並非如此,大部分都這樣思考,都是由於本身思考的太少,將來太過於迷茫,而又保守於不想犯錯而已..........還記得剛畢業的時候那樣一句話:“做一個萬能的東西是萬萬不能的.....也不要整天為以後的因素來進行編碼。” 所以我的答案很簡單:你要清楚的知道你要什麼,我也會給你清楚的答案。
言歸正轉:
KeyChian 是儲存在沙箱之外的儲存資料,相當於Dictionary, 所有應用都可以擷取和儲存,因此當一個軟體卸載之後完全不影響裡面的資料,這樣當軟體重新安裝之後,理所當然的可以擷取裡面的原資料。
這裡我用的還是別人封裝過的一些代碼SFHFKeychainUtils(可以在網上任意下載):
//儲存資料
BOOL s = [SFHFKeychainUtils storeUsername:name andPassword:pswd forServiceName:server updateExisting:NO error:nil];
//擷取密碼
NSString * psw = [SFHFKeychainUtils getPasswordForUsername:name andServiceName:server error:nil];
好吧,此方案完結。
iOS 開發擷取唯一標識