Home > OS >  Alamofire response coming but the same is not coming in "Success case" why? in swift
Alamofire response coming but the same is not coming in "Success case" why? in swift

Time:02-26

Json response is coming but which is not coming in Alamofire Success case why?

Code: I am using Alamofire in APIReqeustManager Class, and calling its service call in login swift file... so here Json response is coming but which is not coming in Alamofire Success case why?

typealias requestCompletionHandler = (APIJSONReponse) -> Void

class APIReqeustManager: NSObject {

static let sharedInstance = APIReqeustManager()

 func serviceCall(param:[String:Any]?,
             method : HTTPMethod,
             loaderNeed : Bool,
             isTokenNeeded : Bool,
             header : [String : String]? = nil,
             url: String
             completionHandler:@escaping requestCompletionHandler) {

let params  = ["jsonrpc" : "2.0", "params" : param ?? nil] as [String : Any?]


sendRequestWithURL(url, method: method, needViewHideShowAfterLoading: needViewHideShowAfterLoading, queryParameters: queryParam, bodyParameters: (param != nil) ? (params as [String : AnyObject]?) : nil, headers: [String : String].self as? [String : String], vc: vc){
    resp in
    print(resp.response ?? "COULDN'T PARSE: \(String(data: resp.data ?? Data(), encoding: .utf8) ?? "")")

    ....
    
}


fileprivate func sendRequestWithURL(_ URL: String,
                                method: HTTPMethod,
                                retryCount: Int = 0,
                                completionHandler:@escaping 
requestCompletionHandler) {

let actualURL: String

var headerParams: HTTPHeaders?

if let headers = headers {
    headerParams = headers as? HTTPHeaders
}
print(headerParams)
print("Actual URL \(actualURL)")

AF.request(actualURL, method:method, parameters: bodyParameters,encoding: JSONEncoding.default, headers: headerParams)
    .responseJSON { response in

        print("Json response \(response)")//response coming
        switch response.result {
        case .success:
            let JSON = response.result as? NSDictionary
                print("JSON inside success: \(JSON)")//nil

                let wrappedResponse = APIJSONReponse.init(
                    data: response.data,
                    dict: response.result as! Dictionary<String, AnyObject>,//Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
                    response: response.response,
                    error: nil, rpcErrorData: nil)
                DispatchQueue.main.async(execute: {
                    completionHandler(wrappedResponse)
                })
        case .failure(let error):
            let error = error
            let wrappedResponse = APIJSONReponse.init(error: error, dataDict: [:])
            completionHandler(wrappedResponse)
            print(error.localizedDescription)
        }
}
}
}

and now calling this in login swift file like below

 func loginService() {

        let param = ["email" : "[email protected]",
                     "password": "12345678"]
        APIReqeustManager.sharedInstance.serviceCall(param: param, method: .post, url: "http://test.com/dev/login", isTokenNeeded: false){ [weak self] (resp) in
            
            print("login response \(resp)")

        }
    }

out put:

with above code if i print print("Json response: \(response)") the the response will be like this

Json response: success({
result =     {
    status = A;
    token = "testtttttttt";
    userdata =         {
        "available_for_serivice" = N;
        "buy_review" = "<null>";
        city = test city;
        "company_name" = test;
       

for the same success response if i print inside Success case then print("JSON inside success: (JSON)")

nil

Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)

Edit: its like this

class APIJSONReponse {
let data: Data?
let dict: Dictionary<String, AnyObject>?
let response: URLResponse?
var error: Error?
var message : String?
var rpcErrorData: ErrorDataModel?

init(response: URLResponse?,error: Error?,rpcErrorData: ErrorDataModel?){

CodePudding user response:

Let's analyze a little:

switch response.result {
case .success:
    let JSON = response.result as? NSDictionary
    print("JSON inside success: \(JSON)")//nil
    ...
case ...
}

So in the switch, you are testing response.result. So if you enter success case, it means that response.result match success, but then, how could it matches NSDictionary too? That doesn't make sense.

Now:

let JSON = response.result as? NSDictionary
print("JSON inside success: \(JSON)")//nil

If JSON is nil, it means it couldn't be cast as a NSDictionary. So that's not the correct type. As said previously, it's a success case, not a NSDictionary.

So later, when you wrote response.result as! Dictionary<String, AnyObject>, the as! meaning crashes if not castable, it's normal behavior then, since it's not castable into a Dictionary<Sting, AnyObject>.

Instead:

switch response.result {
case .success(let json):
    guard let asDict = json as? [String: Any] else { 
        print("json isn't a Dictionary")
        return
    }
    let wrappedResponse = APIJSONReponse(data: response.data,
                                         dict: asDict
                                         response: response.response,
                                         error: nil, 
                                         rpcErrorData: nil)
    ...
case ...
}

Now, I don't don't know why you want to keep response.data, and asDict, that's strange. And I'd recommend to use Codable.

  • Related