我的应用在恢复购买后向服务器发送收据。字典增加了两个额外的键:" bundleId" (app bundle id)," UUID" (app identifierForVendor)。 批准并首次运行后,应用程序一切正常(恢复后我获得所有密钥)。当用户删除应用程序并重新安装时,这些键的值为空值。
获取当前的appStoreReceipt:
if(!self.receiptData){
NSURL *receiptURL = [[NSBundle mainBundle]
appStoreReceiptURL];
self.receiptData = [NSData
dataWithContentsOfURL:receiptURL]
receipt = [self.receiptData bkrBase64EncodedString];
}
else{
receipt = [self.receiptData bkrBase64EncodedString];
}
Apple请求:
if(receipt){
NSError *error;
NSDictionary *requestContents = @{
@"receipt-data" : receipt,
@"password" : //purchaseAppSecreatKey
};
NSData *requestData = [NSJSONSerialization dataWithJSONObject:requestContents
options:0
error:&error];
if (!requestData) { /* ... Handle error ... */
}
// Create a POST request with the receipt data.
NSURL *storeURL = ///iTunesVerificationURL
NSMutableURLRequest *storeRequest =
[NSMutableURLRequest requestWithURL:storeURL];
[storeRequest setHTTPMethod:@"POST"];
[storeRequest setHTTPBody:requestData];
// Make a connection to the iTunes Store on a background queue.
NSOperationQueue *operationQueue = [[NSOperationQueue alloc] init];
[NSURLConnection
sendAsynchronousRequest:storeRequest
queue:operationQueue
completionHandler:^(NSURLResponse *response, NSData *data,
NSError *connectionError) {
if (connectionError) {
NSLog(@"response error %@", connectionError.localizedDescription);
} else {
NSError *error;
NSDictionary *jsonResponse =
[NSJSONSerialization JSONObjectWithData:data
options:0
error:&error] ;
if(!error){
//success, sending to server
}else{
NSLog(@"parse error %@", error.localizedDescription);
}
}
}];
}
发送至服务器代码
NSMutableDictionary *requestBodyDictonary = [NSMutableDictionary dictionaryWithDictionary:reciptDic];
[requestBodyDictonary setObject:[self bundleId] forKey:@"bundleId"];
[requestBodyDictonary setObject:[self UUID] forKey:@"uuid"];
NSURL *url = [NSURL URLWithString:];
NSError *error = nil;
NSData *bodyData = [NSJSONSerialization dataWithJSONObject:requestBodyDictonary options:0 error:&error];
if(error == nil){
NSMutableURLRequest *request = [[NSMutableURLRequest alloc]
initWithURL:url
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:15.0];
[request setHTTPMethod:@"POST"];
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[request setHTTPBody:bodyData];
NSURLSession *defaultstSession = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
NSURLSessionDataTask *task = [defaultstSession dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSLog(@"complete %ld", (long)[(NSHTTPURLResponse *)response statusCode]);
}];
[task resume];
}else{
NSLog(@"error parshe %@", [error localizedDescription]);
}
获取uuid和bundleid
#pragma mark - User ID
-(NSString *)UUID{
if(!_UUID){
_UUID = [[NSUserDefaults standardUserDefaults] stringForKey:@"identifierForVendor_UUID"];
if(!_UUID){
_UUID = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
[[NSUserDefaults standardUserDefaults]setObject:_UUID forKey:@"identifierForVendor_UUID"];
[[NSUserDefaults standardUserDefaults]synchronize];
}
}
return _UUID;
}
#pragma mark bundle id
-(NSString *)bundleId{
if(!_bundleId){
_bundleId = [[NSUserDefaults standardUserDefaults] stringForKey:@"app_BundleId"];
if(!_bundleId){
_bundleId = [[NSBundle mainBundle]bundleIdentifier];
if(!_bundleId){
_bundleId = (__bridge_transfer NSString *)CFDictionaryGetValue(CFBundleGetInfoDictionary(CFBundleGetMainBundle()),
(const void *)(@"CFBundleIdentifier"));
}
[[NSUserDefaults standardUserDefaults] setObject:_bundleId forKey:@"app_BundleId"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
}
return _bundleId;
}
为什么我的应用在重新安装后会返回null? 在沙盒模式下一切正常
答案 0 :(得分:0)
如果您删除APP,那么它也会清除所有NSUserDefault值,我们必须使用钥匙串来存储值,如果您删除应用程序它将保持相同。
使用KeychainItemWrapper文件存储UDID和BundleID
从github下载keychanItemwrapper
#import "KeychainItemWrapper.h"
then set values do Like this:
UIDevice *device = [UIDevice currentDevice];
NSString *div = [[device identifierForVendor]UUIDString];
keychain = [[KeychainItemWrapper alloc] initWithIdentifier:@"TestUDID" accessGroup:nil];
userDevice_id = [keychain objectForKey:(__bridge id)(kSecAttrAccount)];
if([userDevice_id isEqualToString:@""])
{
keychain = [[KeychainItemWrapper alloc] initWithIdentifier:@"TestUDID" accessGroup:nil];
[keychain setObject:div forKey:(__bridge id)(kSecAttrAccount)];
}
从变量中获取值:
keychain = [[KeychainItemWrapper alloc] initWithIdentifier:@"TestUDID" accessGroup:nil];
userDevice_id = [keychain objectForKey:(__bridge id)(kSecAttrAccount)];