0

アプリを Swift 3 に更新していますが、Alamofire と .get リクエストで問題が発生しています。以下のコードを使用して、SkyScanner の API からフライト データを取得するための .get リクエストを作成しています。何らかの理由で、最後の .get リクエストから返される JSON 値は、常に部分的に空の値を返します。更新が完了し、いくつかの要素には正しいデータが含まれているという成功メッセージが表示されますが、旅程情報や航空会社情報などの他の要素は常に空です。

応答のタイプ (JSON、String、Data など) を変更しようとしましたが、問題が解決しないようです。このコードは Swift 2 で正常に機能しましたが、最近の更新ですべてが壊れました。部分的に空の JSON 応答の原因について何か考えはありますか?

import UIKit
import SwiftyJSON
import Alamofire

class ViewController: UIViewController {

var key = "prtl6749387986743898559646983194"

override func viewDidLoad() {
    super.viewDidLoad()

    getFlights()
}

func getSessionKey(destination: String, outboundDate: String, inboundDate: String, adults: Int, complete: @escaping(_ key: String?, _ error: NSError?) -> Void) {
    // Use the mandatory headers listed on the SkyScanner api page http://business.skyscanner.net/portal/en-GB/Documentation/FlightsLivePricingList
    let headers: HTTPHeaders = [
        "Content-Type":"application/x-www-form-urlencoded",
        "Accept":"application/json"
    ]

    let parameters: Parameters = [
        "apiKey":key,
        "country":"US",
        "currency":"USD",
        "locationSchema":"iata",
        "locale":"EN",
        "originplace":"DUB",
        "destinationplace":"LON",
        "outbounddate":"2017-03-12",
        "inbounddate":"2017-03-20",
        "adults":1,
        "groupPricing":true
    ]

    // First get the session URL key so we can being the poll
    let sessionURL = "http://partners.api.skyscanner.net/apiservices/pricing/v1.0"
    let sessionPost = Alamofire.request(sessionURL, method: .post, parameters: parameters, encoding: URLEncoding.default, headers: headers)
    sessionPost.responseString { (sessionResponse) in

        switch sessionResponse.result {
        case .success:
            if let responseHeader = sessionResponse.response?.allHeaderFields {

                // Get the session poll URL from the location header
                let locationHeader = responseHeader["Location"] as? String
                if let range = locationHeader?.range(of: "v1.0/") {
                    let sessionKey = locationHeader?.substring(from: range.upperBound)
                    complete(sessionKey, nil)
                }
            }
        case .failure(let error):
            complete(nil, error as NSError?)
        }
    }
}

func poll(sessionKey: String, complete: @escaping(_ data: JSON?, _ error: NSError?) -> Void) {

    // Take the new found session key and plug it into the poll func
    let pollingParameters: Parameters = [
        "sortype":"price",
        "sortorder":"asc",
        "includeQuery": false,
        "stops": 2,
        "includeCurrencyLookup": false,
        "includeBookingDetailsLink": true
    ]

    let headers: HTTPHeaders = [
        "Content-Type":"application/x-www-form-urlencoded",
        "Accept":"application/json"
    ]

    // **PROBLEM HERE AS THE RETURNED VALUE ALWAYS CONTAINS SOME EMPTY ELEMENTS FOR AN UNDETERMINED REASON**
    let pollURL = "http://partners.api.skyscanner.net/apiservices/pricing/v1.0/\(sessionKey)?apiKey=\(key)"

    let sessionPoll = Alamofire.request(pollURL, method: .get, parameters: pollingParameters, encoding: URLEncoding.default, headers: headers)

    sessionPoll.responseJSON(queue: DispatchQueue.global() ,completionHandler: { (response) in
        print(response.response?.statusCode ?? "There is no response")
        switch response.result {
        case .success:
            if let value = response.result.value {
                //print("RawValue: \(value)")
                complete(JSON(value), nil)
            }
        case .failure(let error):
            complete(nil, error as NSError?)
        }
    })
}

func beginPolling(sessionKey: String, complete: @escaping (_ itineraries: [String:[[String:JSON]]]?, _ error: NSError?) -> Void) {
    self.poll(sessionKey: sessionKey) { (data, error) in
        if error == nil {
            if data?["Status"].stringValue == "UpdatesPending"{
                let when = DispatchTime.now() + 1
                DispatchQueue.global().asyncAfter(deadline: when, execute: {
                    print("Updates Pending")
                    self.beginPolling(sessionKey: sessionKey, complete: { (trips, error) in
                        complete(trips, error)
                    })
                })
            }else if data?["Status"].stringValue == "UpdatesComplete" {
                print("Updates Complete: \(data)")

            }else {
                // There is no Status and we've probably errored out somewhere
            }
        }else{
            // Error
        }
    }
}

func getFlights() {

    getSessionKey(destination: "LON", outboundDate: "2017-03-12", inboundDate: "2017-03-20", adults: 1) { (sessionKey, error) in
        if error == nil{
            let when = DispatchTime.now() + 1
            DispatchQueue.global().asyncAfter(deadline: when, execute: {

                self.beginPolling(sessionKey: sessionKey!, complete: { (trips, error) in
                    if error == nil {
                        // Take the valid data and pass it on to the next viewcontroller
                    }else{
                        // Error
                    }
                })
            })
        }else {
            print("There has been an Error getting the session key")
        }
    }
}

}

4

1 に答える 1

0

誰にも気付かれずにAPIドキュメントが変更されました。「stops」パラメーターは 0 または 1 の値のみを受け入れ、その他の入力は、これまで見てきた奇妙な出力を引き起こします。

于 2017-03-06T11:10:28.270 に答える