我们发布了一个基于订阅的应用,当用户下载该应用时,它会作为试用应用启动。当他们购买应用内订阅时,他们会获得完整的应用。
我们遇到的问题是,如果用户使用手机上的AppStore应用程序安装应用程序,则会获得完整版本(每个用户)。我知道他们没有买任何东西。但是如果他们从iTunes下载应用程序,并使用同步通过计算机将应用程序安装到他们的手机上,该应用程序将作为试用版启动,并且购买订阅的选项就在那里。
我被告知它与itunes索引有关,新版本会修复它,但是今天批准了新版本,我们遇到了同样的问题。
任何帮助都表示赞赏。
波多黎各。
编辑我测试了使用xCode模拟器发送给Apple的相同版本,一个实际的设备,通过adHoc开发并使用iTunes打开ipa,它们都正常工作。不知道还有什么可能发生。
此方法在启动时调用:
// check in App Subscription status
-(void)checkInAppSubscriptionStatus{
NSString *accountType = FMAccountTypeTrial;
// get receipt
NSDictionary *receipt = [[FmIAPHelper sharedInstance] getStoreReceipt:NO];
// if receipt found
if([(NSNumber*)[receipt objectForKey:@"status"] integerValue] == 0){
// get exp date from receipt.
NSString *expDateStr = [[[receipt objectForKey:@"latest_receipt_info"] objectAtIndex:0] objectForKey:@"expires_date"];
NSString *productIdentifier = [[[receipt objectForKey:@"latest_receipt_info"] objectAtIndex:0] objectForKey:@"product_id"];
// set subscription type based on product identifier
NSString *subscriptionType = ([productIdentifier isEqualToString:FMInAppMonthSubscription])? FMSubscriptionTypeMonthly : FMSubscriptionTypeYearly;
expDateStr = [expDateStr stringByReplacingOccurrencesOfString:@"Etc/GMT" withString:@"GMT"];
NSDateFormatter *df = [FM_UIViewController mysqlTimeStampFormatter];
NSDate *expDate = [df dateFromString:expDateStr];
// expiration date has passed.
NSComparisonResult result = [expDate compare:[NSDate date]];
if(result == NSOrderedDescending || result == NSOrderedSame){ // date still valid
accountType = FMAccountTypePremium;
// save data for latest receipt
[[NSUserDefaults standardUserDefaults] setObject:subscriptionType forKey:FMSubscriptionTypeKey]; // monthly or yearly
[[NSUserDefaults standardUserDefaults] setValue:receipt forKey:FMSubscriptionLastReceiptKey]; // last receipt
[[NSUserDefaults standardUserDefaults] synchronize];
}
[[NSUserDefaults standardUserDefaults] setValue:expDate forKey:FMSubscriptionExpDateKey]; // expiration date
}
[[NSUserDefaults standardUserDefaults] setObject:accountType forKey:FMAccountTypeKey]; // premium or trial.
[[NSUserDefaults standardUserDefaults] synchronize]; //save
[self displayInitialContentView:@"InitialView"];
}
这是FMIAPHelper中的getStoreReceipt方法
// get the latest receipt
// this returns an NSDictionary of the app's store receipt, status=0 for good, -1 for bad
- (NSDictionary *) getStoreReceipt:(BOOL)sandbox {
NSArray *objects;
NSArray *keys;
NSDictionary *dictionary;
BOOL gotreceipt = false;
@try {
NSURL *receiptUrl = [[NSBundle mainBundle] appStoreReceiptURL];
if ([[NSFileManager defaultManager] fileExistsAtPath:[receiptUrl path]]) {
NSData *receiptData = [NSData dataWithContentsOfURL:receiptUrl];
NSString *receiptString = [self base64forData:receiptData];
if (receiptString != nil) {
objects = [[NSArray alloc] initWithObjects:receiptString,FMiTunesConnectSharedSecret, nil];
keys = [[NSArray alloc] initWithObjects:@"receipt-data",@"password", nil];
dictionary = [[NSDictionary alloc] initWithObjects:objects forKeys:keys];
NSError *error;
NSData *data = [NSJSONSerialization dataWithJSONObject:dictionary options:NSJSONWritingPrettyPrinted error:&error];
NSString *urlSting = @"https://buy.itunes.apple.com/verifyReceipt";
if (sandbox) urlSting = @"https://sandbox.itunes.apple.com/verifyReceipt";
NSString *postData = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
dictionary = [self getJsonDictionaryWithPostFromUrlString:urlSting andDataString:postData];
if ([dictionary objectForKey:@"status"] != nil) {
if ([[dictionary objectForKey:@"status"] intValue] == 0) {
gotreceipt = true;
}
}
}
}
} @catch (NSException * e) {
gotreceipt = false;
}
if (!gotreceipt) {
objects = [[NSArray alloc] initWithObjects:@"-1", nil];
keys = [[NSArray alloc] initWithObjects:@"status", nil];
dictionary = [[NSDictionary alloc] initWithObjects:objects forKeys:keys];
}
return dictionary;
}
此方法处理试用信息的显示。
// account type
FMAccountType = [[NSUserDefaults standardUserDefaults] objectForKey:FMAccountTypeKey];
if([[[NSUserDefaults standardUserDefaults] objectForKey:FMSubscriptionExemptKey] isEqualToString:FMSubscriptionExempt]) FMAccountType = FMAccountTypePremium;
if(FMAccountType == nil){
FMAccountType = FMAccountTypeTrial;
}
此版本的代码的免除部分是新的,所以我知道不是它。