6

私は Swift 3 で iOS アプリを開発しており、このチュートリアルに従ってレシート検証を実装しようとしています: http://savvyapps.com/blog/how-setup-test-auto-renewable-subscription-ios-app。ただし、チュートリアルは以前のバージョンの Swift を使用して記述されているようで、いくつかの変更を加える必要がありました。これが私の receiveValidation() 関数です:

func receiptValidation() {
    let receiptPath = Bundle.main.appStoreReceiptURL?.path
    if FileManager.default.fileExists(atPath: receiptPath!){
        var receiptData:NSData?
        do{
            receiptData = try NSData(contentsOf: Bundle.main.appStoreReceiptURL!, options: NSData.ReadingOptions.alwaysMapped)
        }
        catch{
            print("ERROR: " + error.localizedDescription)
        }
        let receiptString = receiptData?.base64EncodedString(options: NSData.Base64EncodingOptions(rawValue: 0))
        let postString = "receipt-data=" + receiptString! + "&password=" + SUBSCRIPTION_SECRET
        let storeURL = NSURL(string:"https://sandbox.itunes.apple.com/verifyReceipt")!
        let storeRequest = NSMutableURLRequest(url: storeURL as URL)
        storeRequest.httpMethod = "POST"
        storeRequest.httpBody = postString.data(using: .utf8)
        let session = URLSession(configuration:URLSessionConfiguration.default)
        let task = session.dataTask(with: storeRequest as URLRequest) { data, response, error in
            do{
                let jsonResponse:NSDictionary = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableContainers) as! NSDictionary
                let expirationDate:NSDate = self.expirationDateFromResponse(jsonResponse: jsonResponse)!
                self.updateIAPExpirationDate(date: expirationDate)
            }
            catch{
                print("ERROR: " + error.localizedDescription)
            }
        }
        task.resume()
    }
}

この問題は、expirationDateFromResponse() メソッドを呼び出そうとすると発生します。このメソッドに渡される jsonResponse には、 のみが含まれていることがわかりますstatus = 21002;。これを調べたところ、「領収書データ プロパティのデータの形式が正しくないか、欠落しています」という意味です。ただし、私がテストしているデバイスには、製品の有効なサンドボックス サブスクリプションがあり、サブスクリプションはこの問題を除けば正しく機能しているようです。領収書データの値が正しく読み取られてエンコードされるようにするために、他に何かする必要がありますか、またはこの問題を引き起こしている可能性のある他の問題はありますか?

編集:

storeRequest.httpBody を設定する別の方法を試しました。

func receiptValidation() {
    let receiptPath = Bundle.main.appStoreReceiptURL?.path
    if FileManager.default.fileExists(atPath: receiptPath!){
        var receiptData:NSData?
        do{
            receiptData = try NSData(contentsOf: Bundle.main.appStoreReceiptURL!, options: NSData.ReadingOptions.alwaysMapped)
        }
        catch{
            print("ERROR: " + error.localizedDescription)
        }
        let receiptString = receiptData?.base64EncodedString(options: NSData.Base64EncodingOptions(rawValue: 0)) //.URLEncoded
        let dict = ["receipt-data":receiptString, "password":SUBSCRIPTION_SECRET] as [String : Any]
        var jsonData:Data?
        do{
            jsonData = try JSONSerialization.data(withJSONObject: dict, options: .prettyPrinted)
        }
        catch{
            print("ERROR: " + error.localizedDescription)
        }
        let storeURL = NSURL(string:"https://sandbox.itunes.apple.com/verifyReceipt")!
        let storeRequest = NSMutableURLRequest(url: storeURL as URL)
        storeRequest.httpMethod = "POST"
        storeRequest.httpBody = jsonData!
        let session = URLSession(configuration:URLSessionConfiguration.default)
        let task = session.dataTask(with: storeRequest as URLRequest) { data, response, error in
            do{
                let jsonResponse:NSDictionary = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableContainers) as! NSDictionary
                let expirationDate:NSDate = self.expirationDateFromResponse(jsonResponse: jsonResponse)!
                self.updateIAPExpirationDate(date: expirationDate)
            }
            catch{
                print("ERROR: " + error.localizedDescription)
            }
        }
        task.resume()
    }
}

ただし、このコードでアプリを実行すると、行に到達するとハングしますjsonData = try JSONSerialization.data(withJSONObject: dict, options: .prettyPrinted)。catch ブロックにたどり着くことさえできず、何もしなくなります。私がオンラインで見たものから、他の人は JSONSerialization.data を使用して Swift 3 でリクエスト httpBody を設定するのに問題があるようです。

4

6 に答える 6

0

最終的に、この回答に示されているように、アプリで Python で記述された Lambda 関数を呼び出すことで問題を解決することができました。Swift コードの何が問題だったのか、または Swift 3 でこれを完全に行う方法はまだわかりませんが、いずれにしても Lambda 関数は望ましい結果を得ました。

于 2016-10-01T03:27:21.607 に答える