स्विफ्ट अल्मोफायर: HTTP प्रतिक्रिया स्थिति कोड कैसे प्राप्त करें


106

मैं अनुरोध विफलताओं (और आदर्श रूप से सफलताओं के लिए भी) के लिए HTTP प्रतिक्रिया स्थिति कोड (जैसे 400, 401, 403, 503, आदि) को पुनः प्राप्त करना चाहूंगा। इस कोड में, मैं HTTP बेसिक के साथ उपयोगकर्ता प्रमाणीकरण कर रहा हूं और उपयोगकर्ता को यह संदेश देने में सक्षम होना चाहता हूं कि उपयोगकर्ता द्वारा अपना पासवर्ड गलत किए जाने पर प्रमाणीकरण विफल हो गया।

Alamofire.request(.GET, "https://host.com/a/path").authenticate(user: "user", password: "typo")
    .responseString { (req, res, data, error) in
        if error != nil {
            println("STRING Error:: error:\(error)")
            println("  req:\(req)")
            println("  res:\(res)")
            println("  data:\(data)")
            return
        }
        println("SUCCESS for String")
}
    .responseJSON { (req, res, data, error) in
        if error != nil {
            println("JSON Error:: error:\(error)")
            println("  req:\(req)")
            println("  res:\(res)")
            println("  data:\(data)")
            return
        }
        println("SUCCESS for JSON")
}

दुर्भाग्य से, उत्पन्न त्रुटि यह संकेत नहीं देती है कि HTTP स्थिति कोड 409 वास्तव में प्राप्त किया गया था:

STRING Error:: error:Optional(Error Domain=NSURLErrorDomain Code=-999 "cancelled" UserInfo=0x7f9beb8efce0 {NSErrorFailingURLKey=https://host.com/a/path, NSLocalizedDescription=cancelled, NSErrorFailingURLStringKey=https://host.com/a/path})
  req:<NSMutableURLRequest: 0x7f9beb89d5e0> { URL: https://host.com/a/path }
  res:nil
  data:Optional("")
JSON Error:: error:Optional(Error Domain=NSURLErrorDomain Code=-999 "cancelled" UserInfo=0x7f9beb8efce0 {NSErrorFailingURLKey=https://host.com/a/path, NSLocalizedDescription=cancelled, NSErrorFailingURLStringKey=https://host.com/a/path})
  req:<NSMutableURLRequest: 0x7f9beb89d5e0> { URL: https://host.com/a/path }
  res:nil
  data:nil

इसके अतिरिक्त, त्रुटि होने पर HTTP निकाय को पुनः प्राप्त करना अच्छा होगा क्योंकि मेरा सर्वर-साइड वहाँ त्रुटि का एक पाठ विवरण डाल देगा।

प्रश्न
क्या गैर-2xx प्रतिक्रिया पर स्थिति कोड प्राप्त करना संभव है?
क्या 2xx प्रतिक्रिया पर विशिष्ट स्थिति कोड प्राप्त करना संभव है?
क्या गैर-2xx प्रतिक्रिया पर HTTP निकाय को पुनः प्राप्त करना संभव है?

धन्यवाद!


1
यदि आप अयोग्य हैं तो आपको डिज़ाइन द्वारा -999 प्राप्त होता है। निश्चित नहीं है कि यह क्यों है या इसे कैसे हल किया जा सकता है ... क्या आपने इसे हल किया?
गुइडो हेंड्रिक्स

जवाबों:


187

के लिए स्विफ्ट 3.x / स्विफ्ट 4.0 / स्विफ्ट 5.0 के साथ उपयोगकर्ताओं को Alamofire> = 4.0 / Alamofire> = 5.0


response.response?.statusCode

अधिक क्रिया उदाहरण:

Alamofire.request(urlString)
        .responseString { response in
            print("Success: \(response.result.isSuccess)")
            print("Response String: \(response.result.value)")

            var statusCode = response.response?.statusCode
            if let error = response.result.error as? AFError {  
                statusCode = error._code // statusCode private                 
                switch error {
                case .invalidURL(let url):
                    print("Invalid URL: \(url) - \(error.localizedDescription)")
                case .parameterEncodingFailed(let reason):
                    print("Parameter encoding failed: \(error.localizedDescription)")
                    print("Failure Reason: \(reason)")
                case .multipartEncodingFailed(let reason):
                    print("Multipart encoding failed: \(error.localizedDescription)")
                    print("Failure Reason: \(reason)")
                case .responseValidationFailed(let reason):
                    print("Response validation failed: \(error.localizedDescription)")
                    print("Failure Reason: \(reason)")

                    switch reason {
                    case .dataFileNil, .dataFileReadFailed:
                        print("Downloaded file could not be read")
                    case .missingContentType(let acceptableContentTypes):
                        print("Content Type Missing: \(acceptableContentTypes)")
                    case .unacceptableContentType(let acceptableContentTypes, let responseContentType):
                        print("Response content type: \(responseContentType) was unacceptable: \(acceptableContentTypes)")
                    case .unacceptableStatusCode(let code):
                        print("Response status code was unacceptable: \(code)")
                        statusCode = code
                    }
                case .responseSerializationFailed(let reason):
                    print("Response serialization failed: \(error.localizedDescription)")
                    print("Failure Reason: \(reason)")
                    // statusCode = 3840 ???? maybe..
                default:break
                }

                print("Underlying error: \(error.underlyingError)")
            } else if let error = response.result.error as? URLError {
                print("URLError occurred: \(error)")
            } else {
                print("Unknown error: \(response.result.error)")
            }

            print(statusCode) // the status code
    } 

(Alamofire 4 में एक पूरी तरह से नई त्रुटि प्रणाली है, विवरण के लिए यहां देखें)

के लिए स्विफ्ट 2.x के साथ उपयोगकर्ताओं को Alamofire> = 3.0

Alamofire.request(.GET, urlString)
      .responseString { response in
             print("Success: \(response.result.isSuccess)")
             print("Response String: \(response.result.value)")
             if let alamoError = response.result.error {
               let alamoCode = alamoError.code
               let statusCode = (response.response?.statusCode)!
             } else { //no errors
               let statusCode = (response.response?.statusCode)! //example : 200
             }
}

उदाहरण के लिए response.result.error आपको एक Alamofire त्रुटि दे सकता है। StatusCodeValidationFailed, FAILURE: Error Domain=com.alamofire.error Code=-6003। यदि आप वास्तव में HTTP प्रतिसाद त्रुटि प्राप्त करना चाहते हैं तो यह उपयोगकर्ता के लिए बेहतर हैresponse.response?.statusCode
Kostiantyn Koval

@KostiantynKoval मैं आपसे सहमत हूं, आपने एक उचित स्पष्टीकरण दिया है। मैंने अपने उत्तर को स्पष्टता के लिए अद्यतन किया
Alessandro Ornano

50

responseनीचे दिए गए तर्क के साथ पूरा करने वाले हैंडलर में मुझे लगता है कि http स्थिति कोड है response.response.statusCode:

Alamofire.request(.POST, urlString, parameters: parameters)
            .responseJSON(completionHandler: {response in
                switch(response.result) {
                case .Success(let JSON):
                    // Yeah! Hand response
                case .Failure(let error):
                   let message : String
                   if let httpStatusCode = response.response?.statusCode {
                      switch(httpStatusCode) {
                      case 400:
                          message = "Username or password not provided."
                      case 401:
                          message = "Incorrect password for user '\(name)'."
                       ...
                      }
                   } else {
                      message = error.localizedDescription
                   }
                   // display alert with error message
                 }

हाय, क्या स्टेटसकोड 200 फेल हो जाएगा? मेरा अनुरोध सर्वर की तरफ से सही ढंग से संभाला गया था, लेकिन प्रतिक्रिया विफलता के अंतर्गत आती है
perwyl

1
@perwyl मुझे नहीं लगता कि 200 एक http त्रुटि है: देखें stackoverflow.com/questions/27921537/…
wcochran

2
@perwyl स्थिति कोड 200 सफलता का संकेत है, यदि आपके सर्वर लौटे 200 और प्रतिक्रिया का संकेत त्रुटि (यानी कुछ संपत्ति issuccess बुलाया = false), तो आप को संभाल करने के लिए है कि अपने दृश्यपटल कोड में
Parama Dharmika

16
    Alamofire
        .request(.GET, "REQUEST_URL", parameters: parms, headers: headers)
        .validate(statusCode: 200..<300)
        .responseJSON{ response in

            switch response.result{
            case .Success:
                if let JSON = response.result.value
                {
                }
            case .Failure(let error):
    }

यह एपी की सर्वोत्तम प्रथाओं को उत्तेजित करता है
CESCO

यूआरडब्ल्यू :) आपके अनुरोधों के लिए राउटर को लागू करने का प्रयास करें। ;)
183 बजे Abo3atef

11

एलोफायर का उपयोग करके स्थिति कोड प्राप्त करने का सबसे अच्छा तरीका है।

 Alamofire.request (URL) .responseJSON {
  में प्रतिक्रिया

  चलो स्थिति = response.response? .statusCode
  प्रिंट ("स्टेटस \" (स्थिति) ")

}

5

अपनी responseJSONपूर्णता में, आप प्रतिक्रिया ऑब्जेक्ट से स्थिति कोड प्राप्त कर सकते हैं, जिसमें एक प्रकार है NSHTTPURLResponse?:

if let response = res {
    var statusCode = response.statusCode
}

यह इस बात पर ध्यान दिए बिना काम करेगा कि स्थिति कोड त्रुटि सीमा में है या नहीं। अधिक जानकारी के लिए, NSHTTPURLResponse प्रलेखन देखें

अपने अन्य प्रश्न के लिए, आप responseStringकच्चे प्रतिक्रिया निकाय को प्राप्त करने के लिए फ़ंक्शन का उपयोग कर सकते हैं । आप इसके अतिरिक्त जोड़ सकते हैं responseJSONऔर दोनों को बुलाया जाएगा।

.responseJson { (req, res, json, error) in
   // existing code
}
.responseString { (_, _, body, _) in
   // body is a String? containing the response body
}

3

आपकी त्रुटि इंगित करती है कि ऑपरेशन किसी कारण से रद्द किया जा रहा है। मुझे यह समझने के लिए अधिक विवरणों की आवश्यकता होगी कि क्यों। लेकिन मुझे लगता है कि बड़ा मुद्दा यह हो सकता है कि चूंकि आपका समापन बिंदु https://host.com/a/pathफर्जी है, इसलिए रिपोर्ट करने के लिए कोई वास्तविक सर्वर प्रतिक्रिया नहीं है, और इसलिए आप देख रहे हैं nil

यदि आप एक उचित एंडपॉइंट को हिट करते हैं, जो उचित प्रतिक्रिया देता है, तो आपको resकिसी NSURLHTTPResponseऑब्जेक्ट के रूप में किसी ऑब्जेक्ट के रूप में (तकनीकों सैम उल्लेख का उपयोग करके) जैसे गुणों के साथ एक गैर-शून्य मान देखना चाहिए statusCode

इसके अलावा, बस स्पष्ट होने के लिए, errorप्रकार का है NSError। यह बताता है कि नेटवर्क अनुरोध विफल क्यों हुआ। सर्वर साइड पर विफलता की स्थिति कोड वास्तव में प्रतिक्रिया का एक हिस्सा है।

आशा है कि आपके मुख्य प्रश्न का उत्तर देने में मदद करता है।


अच्छी पकड़, मैं भी नीचे प्रश्नों की सूची पर केंद्रित था।
सैम

1
यह वास्तव में एक कोड 401 अनधिकृत प्राप्त कर रहा है क्योंकि मैं जानबूझकर गलत पासवर्ड भेज रहा हूं ताकि किसी उपयोगकर्ता को उनके पासवर्ड को गलत तरीके से अनुकरण कर सकें ताकि मैं उस मामले को पकड़ सकूं और उपयोगकर्ता की प्रतिक्रिया दे सकूं। वह वास्तविक URL नहीं है जिसका मैं उपयोग कर रहा हूं, लेकिन मैं एक कानूनी URL का उपयोग कर रहा हूं जिसका परिणाम सही पासवर्ड भेजने पर सफलता के रूप में मिलता है। मेरे मूल पोस्ट में कंसोल आउटपुट वास्तविक URL (वास्तविक URL को छोड़कर) को हिट करने से वास्तविक आउटपुट है और आप देख सकते हैं कि resऑब्जेक्ट है nil, इसलिए यह उत्तर मदद नहीं करता है, क्षमा करें।
ग्रेग

स्पष्टीकरण देने के लिए धन्यवाद। ठीक है, तो केवल एक चीज जो यहां संदिग्ध है, -999 त्रुटि है जिसका मैंने सामना नहीं किया है, लेकिन प्रलेखन से पता चलता है कि अनुरोध रद्द किया जा रहा है (इसलिए यहां तक ​​कि एक प्रतिक्रिया प्राप्त करने का सवाल भी मूक होना चाहिए)। क्या आपने किसी भिन्न प्रकार की त्रुटि के लिए प्रतिक्रिया वस्तु को मुद्रित करने का प्रयास किया है जो कि संबंधित नहीं है? बस उत्सुक।
रेनिपिक्सल

अहह मैंने सोचा errorकि स्थिति कोड के साथ प्रतिक्रियाओं का जिक्र था जो उस सीमा से बाहर हैं जो हम प्रदान करते हैं validate()। धन्यवाद!!!
जेराल्ड

3

या पैटर्न मिलान का उपयोग करें

if let error = response.result.error as? AFError {
   if case .responseValidationFailed(.unacceptableStatusCode(let code)) = error {
       print(code)
   }
}

एक जादू की तरह काम किया।
अलास्का

3

आप स्थिति कोड हैंडलर के लिए निम्नलिखित कोड की जाँच कर सकते हैं

    let request = URLRequest(url: URL(string:"url string")!)    
    Alamofire.request(request).validate(statusCode: 200..<300).responseJSON { (response) in
        switch response.result {
        case .success(let data as [String:Any]):
            completion(true,data)
        case .failure(let err):
            print(err.localizedDescription)
            completion(false,err)
        default:
            completion(false,nil)
        }
    }

यदि स्थिति कोड मान्य नहीं है, तो यह स्विच केस में विफलता दर्ज करेगा


1

Swam 2.0 के लिए Alamofire> 2.0 के साथ उपयोगकर्ता

Alamofire.request(.GET, url)
  .responseString { _, response, result in
    if response?.statusCode == 200{
      //Do something with result
    }
}

1

मुझे यह जानने की जरूरत है कि वास्तविक त्रुटि कोड नंबर कैसे प्राप्त करें।

मुझे किसी और से एक प्रोजेक्ट विरासत में मिला है और मुझे एक .catchक्लॉज से त्रुटि कोड प्राप्त करना था जो कि उन्होंने पहले Alamofire के लिए सेटअप किया था:

} .catch { (error) in

    guard let error = error as? AFError else { return }
    guard let statusCode = error.responseCode else { return }

    print("Alamofire statusCode num is: ", statusCode)
}

या अगर आपको इसे responseमूल्य से प्राप्त करने की आवश्यकता है @ mbryzinski के उत्तर का पालन ​​करें

Alamofire ... { (response) in

    guard let error = response.result.error as? AFError else { return }
    guard let statusCode = error.responseCode else { return }

    print("Alamofire statusCode num is: ", statusCode)
})
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.