私の公開アプリケーションは、デバイスを識別するためにCFUUID
andを使用します (また、アプリがアンインストールされて再インストールされても、その ID は変更されません)。SSKeychain
私はそれらのデバイス ID をサーバーに保存していますが、最近、一部のユーザーが同じ実際のデバイスに対してこれらの ID を複数持っていることに気付きました。私が見る唯一の説明は、ID がキーチェーンから保存またはロードされていないため、デバイスが新しい ID を生成するということです。奇妙なことに、同じ iOS バージョンを実行している他のデバイスでも問題なく動作します。
何が起こっているのかについてのアイデアはありますか?
これは私の関連コードです(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
NSString* identifier = @"appName";
NSString* serviceName = @"com.company.appName";
NSString *retrieveuuid = [SSKeychain passwordForService:serviceName account:identifier];
if (retrieveuuid == nil) {
CFUUIDRef theUUID = CFUUIDCreate(NULL);
CFStringRef string = CFUUIDCreateString(NULL, theUUID);
CFRelease(theUUID);
NSString *uuid = (NSString*) string;
[SSKeychain setPassword:uuid forService:serviceName account:identifier];
}
編集:retrieveuuid == nil
何らかの理由で期待どおりに機能していないと思います。アプリの後半でプッシュ通知を登録し、まったく同じ行で読み取ったこのCFUUIDとともにプッシュトークンをサーバーに送信し[SSKeychain passwordForService:serviceName account:identifier]
ますが、サーバーに送信されるとnilではありません(したがって、同じプッシュ トークン)。
EDIT 2 を追加して、実際のコードを追加します。
AppDelegate.m
NSString* identifier = @"appName";
NSString* serviceName = @"com.company.appName";
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//Creating UUID
NSString *retrieveuuid = [AppDelegate getDeviceId];
if (retrieveuuid == nil) {
CFUUIDRef theUUID = CFUUIDCreate(NULL);
CFStringRef string = CFUUIDCreateString(NULL, theUUID);
CFRelease(theUUID);
NSString *uuid = (NSString*) string;
[SSKeychain setPassword:uuid forService:serviceName account:identifier];
}
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:
(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
}
+ (NSString*) getDeviceId {
return [SSKeychain passwordForService:serviceName account:identifier];
}
- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken
{
NSString *newToken = [deviceToken description];
newToken = [newToken stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];
newToken = [newToken stringByReplacingOccurrencesOfString:@" " withString:@""];
_deviceToken = [[NSString alloc] initWithString:newToken];
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSString *user = [prefs objectForKey:@"appNameUsername"];
if(user && ![user isEqualToString:@""]){
RestClient *rest = [[RestClient alloc] init];
rest.delegate = self;
rest.tag = 2;
[rest updateToken:newToken ForUsername:user];
[rest release];
}
}
RestClient.m
-(void) updateToken:(NSString *)token ForUsername:(NSString *)userName{
NSArray* info = [NSArray arrayWithObject: [NSMutableDictionary dictionaryWithObjectsAndKeys:
userName, @"Username",
token, @"TokenNo",
[[UIDevice currentDevice].model hasPrefix:@"iPad"] ? @"iPad" : @"iPhone", @"Device",
[UIDevice currentDevice].systemVersion, @"OSVersion",
[AppDelegate getDeviceId], @"DeviceID",
@"updateToken", @"CMD",
nil]];
[self doAction:info];
}
doAction メソッドはデータをサーバーに送信し、デリゲートをコールバックするだけで、その部分は正常に機能します。このコマンドを受信したログをサーバーで確認できます。
"JSONCMD":"[
{ "TokenNo" : "f0d3aa21758350333b7e6315c38_EDIT_257c1838f49c43049f8380ec1ff63",
"AppVersion" : "1.0.4",
"Username" : "user@server.com",
"CMD" : "updateToken",
"OSVersion" : "7.0.4",
"DeviceID" : "9B794E11-6EF7-470C-B319-5A9FCCDAFD2B",
"Device" : "iPhone"
}
]
NSStrings
コントローラー本体と静的getDevice
メソッドの2つの候補が奇妙な動作を引き起こしている可能性があります。ただし、これが多くのデバイスでどのように機能するかはわかりませんが、他のデバイスでは失敗します。