Ios 将付费应用程序更改为免费,但知道用户以前是否购买过该应用程序

Ios 将付费应用程序更改为免费,但知道用户以前是否购买过该应用程序,ios,in-app-purchase,Ios,In App Purchase,我正在考虑将我的付费iOS应用程序更改为免费,使其基于广告,并拥有应用程序内购买选项以删除广告 如果我刚刚发布这个应用程序,这听起来是个好主意,但我们有超过3万次付费下载,我不希望这些用户在更新到新的免费版本时看到广告 我在这里有什么选择吗?不,没有。你能做的最好是发布一个更新,而它仍然是一个付费应用程序,向NSUserDefaults(或应用程序数据目录中的一个文件,不管哪个)写入一些值,表明它已购买。等待一周或你想要多长时间,然后发布一个删除该代码的更新,时间定在价格变为免费的同一天发布。唯

我正在考虑将我的付费
iOS
应用程序更改为免费,使其基于广告,并拥有
应用程序内购买
选项以删除广告

如果我刚刚发布这个应用程序,这听起来是个好主意,但我们有超过3万次付费下载,我不希望这些用户在更新到新的免费版本时看到广告


我在这里有什么选择吗?

不,没有。你能做的最好是发布一个更新,而它仍然是一个付费应用程序,向NSUserDefaults(或应用程序数据目录中的一个文件,不管哪个)写入一些值,表明它已购买。等待一周或你想要多长时间,然后发布一个删除该代码的更新,时间定在价格变为免费的同一天发布。

唯一的选择是发布两个更新。第一个将向NSUserDefaults写入一个值,将其标识为购买者。第二个更新是您的广告支持版本,它可以读取此买家识别值并隐藏广告。

如果您当前的应用程序在用户默认值或钥匙链中有任何数据,则该数据可以作为指示器。首次打开应用程序时(在新版本中),请运行以下代码:

  • 检查默认值/钥匙链中的数据
  • 如果找到,启用付费内容/禁用广告
  • 将该数据迁移到新密钥(这样您就不会再次升级/免费赠送)

  • 从iOS 7开始,这可以通过正确的收据验证来完成。在iOS 7下,您可以获得购买应用的收据。收据中的部分数据包括用户购买应用程序的原始版本信息。您可以查看该版本,如果它是从发布更新之前到IAP免费,您可以选择为用户提供完整的功能,而无需用户再次购买升级

    当然,如果您希望更新后的应用程序在iOS 6下工作,这不是一个选项


    有关收据验证的详细信息,请参见。

    在付费应用程序启动时提供免费InApp购买是否更容易。显示“升级”之类的按钮。然后在下一次更新时将免费inapp切换为付费?

    在itunes connect中,您可以为应用内购买生成促销代码。您可以为高级功能创建IAP项目,并手动将其作为促销提供给购买者。虽然这不是一个自动的解决方案,但它可能会让你免于一些头痛

    尝试获取所有收据并通过以下数据进行分析:

    "expires_date" = "2017-09-24 11:25:19 Etc/GMT";
    "original_purchase_date" = "2017-09-24 11:20:21 Etc/GMT";
    "product_id" = "com.yourapp.service";
    
    1。从应用商店获取所有用户的收据

    + (NSArray*)all_receipts{
        // Load the receipt from the app bundle.
        NSURL *receiptURL = [[NSBundle mainBundle]appStoreReceiptURL];
        NSData *receipt = [NSData dataWithContentsOfURL:receiptURL];
        if(!receipt){
            //no receipts yet...
            return nil;     
        }
    
        NSError *error;
        NSDictionary *requestContents = @{@"receipt-data": [receipt base64EncodedStringWithOptions:0],
                                          @"password":YOUR_SECRED_SHARED};
        NSData *requestData = [NSJSONSerialization dataWithJSONObject:requestContents
                                                              options:0
                                                                error:&error];
        if (!requestData) {
            return [NSArray array];
        }
    
        // Create a POST request with the receipt data.
        //get current qa / production url
        BOOL sandbox = [[receiptURL lastPathComponent]isEqualToString:@"sandboxReceipt"];
        NSURL *storeURL = [NSURL URLWithString:@"https://buy.itunes.apple.com/verifyReceipt"];
        if (sandbox) {
            storeURL = [NSURL URLWithString:@"https://sandbox.itunes.apple.com/verifyReceipt"];
        }
        NSDictionary *jsonResponse = [LTServer postUrl:storeURL.absoluteString attach:requestContents];
        NSLog(@"jsonResponse %@",jsonResponse);
        if(!jsonResponse){
            return [NSArray array];
        }
        NSArray *receipts_data = jsonResponse[@"latest_receipt_info"];
        return [receipts_data mutableCopy];
    }
    
    2。每张收据将包含一本字典:

        "expires_date" = "2017-09-24 11:25:19 Etc/GMT";
        "expires_date_ms" = 1506252319000;
        "expires_date_pst" = "2017-09-24 04:25:19 America/Los_Angeles";
        "is_trial_period" = true;
        "original_purchase_date" = "2017-09-24 11:20:21 Etc/GMT";
        "original_purchase_date_ms" = 1506252021000;
        "original_purchase_date_pst" = "2017-09-24 04:20:21 America/Los_Angeles";
        "original_transaction_id" = 1000000339209266;
        "product_id" = "com.yourapp.service";
        "purchase_date" = "2017-09-24 11:20:19 Etc/GMT";
        "purchase_date_ms" = 1506252419000;
        "purchase_date_pst" = "2016-11-27 04:20:19 America/Los_Angeles";
        quantity = 1;
        "transaction_id" = 1000000337203266;
        "web_order_line_item_id" = 1000000030161297;
    


    你是否在用户默认值/钥匙链中存储任何东西?是的,如果他们使用公制或非公制,则存储。我不会切换到免费,30k很好:-)是的,但如果有人在过去购买了应用程序,然后在我发布免费版本后在将来重新下载该应用程序,这将不起作用。@NicHubbard,这实际上是不可能自动处理的。您需要为使用自定义URL方案或类似方案的用户提供升级路径。@NicHubbard当前版本是否向NSUserDefaults、keychain或Documents目录写入任何内容?在应用程序将任何内容写入持久性存储之前,您可以检查免费版本中的内容。@neilco是的。我的问题是,如果一个用户购买了我的应用程序,并且已经删除了它。如果他们选择再次下载,或者有一部新手机,他们就不会将这些密钥写入NSUserDefaults。@NicHubbard这些是边缘案例,不幸的是,他们会错过。是的,我认为它不会起作用。因为有些用户可能会暂时不升级,然后最终升级到第二个“免费”版本,这将打破这种情况。怎么会这样呢?关键是,任何使用旧应用程序的人都将拥有原始密钥。任何升级或安装了新版本的人都将拥有新的密钥。比如说,他们一年前就拥有了该应用程序,之后又将其删除,他们还拥有一部新iPhone。他们去他们的“购买”列表,重新下载我的应用程序,因为他们以前买过。我看不出有什么办法可以知道他们付了钱。@NicHubbard在这种情况下你必须验证收据。我也这么想。我执行Wain建议的所有步骤,但如果它们都失败了,我只执行一次收据验证,并根据验证结果设置钥匙链数据。@applefreak如果这些步骤失败,它们会在所有新安装中失败,这不意味着每次新安装都会进行收据验证吗?也就是说,如果用户是第一次安装应用程序,步骤1和2将失败。在什么时候,我们不必进行收据验证?这听起来是个好主意,但我需要回到iOS5。我同意Matthias的观点。假设绝大多数新收入将来自iOS7,只需向iOS6及以下版本提供功能/etc即可。这样一切都会简单得多。Nic,您应该接受rmaddy的回答。或者您可以通过消息从旧系统中删除“pro”功能以更新其系统。此外,在较旧的系统中,您需要测试的功能也会减少。收据中是否包含有关该应用在付费时是否下载了促销代码的信息?谷歌搜索了一段时间,但我似乎找不到答案。我如何才能获得appstore购买的原始购买日期而不是应用内购买?这对于已经购买了应用但已将其删除的用户来说是个问题。如果他们在几个月后再次下载,因此错过了“升级”按钮的应用程序版本。他们只需安装更新,这将是一个免费版本,其中当然包含广告。在iTunesConnect(现在称为AppstoreConnect)上,通过应用程序更新,您(非常)被限制为100个促销代码,每个促销代码在创建后28天内都将处于“活动”状态。随着3万个应用程序的销售,我认为这不是一个现实的问题