Search code examples
swiftalamofire

Alamofire 5.X Type of Expression is Ambiguous Without More Context


I've been debugging this for hours and I have discovered I absolutely despise Swift's error message of Type of expression is ambiguous without more context ---- This code worked with Alamofire 3, 4, and obviously with Alamofire 5 there's some changes to the way it works, but this is essentially what I've found elsewhere which means that something I'm doing is wrong but I have no g darn idea what it could be.

let urlString = "\(baseURL)\(header)"
let jsonData : Data = try! JSONSerialization.data(withJSONObject: parameter, options: .prettyPrinted)
            
let jsonString = NSString(data: jsonData, encoding: String.Encoding.utf8.rawValue)! as String
            
print("JSON Params->\(jsonString)")
            
            let headers: HTTPHeaders = [
                "Authorization": "XXXXXX",
                "Accept": "application/json",
                "Content-Type": "application/json"
            ]
            
            
            let uploadUrl = try! URLRequest(url: URL(string:urlString)!, method: .post, headers: headers)
            AF.upload(
                multipartFormData: { (multiPart) in
                var keys = [String]()
                
                for (key, img) in images {
                    if let imageData = img.jpegData(compressionQuality: compressRatio) {
                        multiPart.append(imageData, withName: key, fileName: key+".png", mimeType: "image/png")
                        keys.append(key)
                    }
                }
                
                let jsonName = try! JSONSerialization.data(withJSONObject: ["count": keys.count], options: .prettyPrinted)
                
                multiPart.append(jsonName, withName: "names")
                multiPart.append(jsonData, withName: "data")
            }, with: uploadUrl, encodingCompletion: { encodingResult in
                switch encodingResult {
                case .success(let upload, _, _):
                    upload.responseJSON{ response in
                        if hud{
                            Loader.init().hide(delegate: vc)
                        }
                        
                        switch response.result {
                        case .success(_):
                            print("Response->\(response.value)")
                            
                            if response.value != nil {
                                let JSON = response.value! as AnyObject
                                let response = JSON["response"] as! NSDictionary
                                
                                let success = response.value(forKey: "status")
                                let success_message = response.value(forKey: "success_message")
                                let error_message = response.value(forKey: "error_message")
                                
                                if success as! String {
                                    completion(response.replaceNullsWithBlanks() as NSDictionary, success_message as NSString, true)
                                } else {
                                    print("Upload failed")
                                    completion([:], error_message as NSString, false)
                                    
                                    if alertMsg {
                                        self.presentAlertWithTitle(title: "Alert", message: error_message, vc: vc)
                                    }
                                }
                            }
                            break
                            
                        case .failure:
                            print(response.error ?? "Fail")
                            self.presentAlertWithTitle(title: "Error!", message: (response.error?.localizedDescription)!, vc: vc)
                            break
                        }
                    }
                case .failure(let error):
                    self.presentAlertWithTitle(title: "Error!", message: error.localizedDescription, vc: vc)
                }
            })

Solution

  • I ended up fixing it using .responseDecoable, I had to define my own Decodable

    let urlString = "\(baseURL)\(header)"
                let jsonData : Data = try! JSONSerialization.data(withJSONObject: parameter, options: .prettyPrinted)
                
                let jsonString = String(data: jsonData, encoding: String.Encoding(rawValue: String.Encoding.utf8.rawValue))
                
                print("JSON Params->\(jsonString!)")
                
                let headers: HTTPHeaders = [
                    "Authorization": "XXXXXX",
                    "Accept": "application/json",
                    "Content-Type": "application/json"
                ]
                
                struct DecodableType: Decodable {
                    let success_message: String
                }
                
                struct UploadResponse: Decodable {
                    let response: DecodableType
                }
                
                let uploadUrl = try! URLRequest(url: URL(string:urlString)!, method: .post, headers: headers)
                AF.upload(
                    multipartFormData: { (multiPart) in
                    var keys = [String]()
                    
                    for (key, img) in images {
                        if let imageData = img.jpegData(compressionQuality: compressRatio) {
                            multiPart.append(imageData, withName: key, fileName: key+".png", mimeType: "image/png")
                            keys.append(key)
                        }
                    }
                    
                    let jsonName = try! JSONSerialization.data(withJSONObject: ["count": keys.count], options: .prettyPrinted)
                    
                    multiPart.append(jsonName, withName: "names")
                    multiPart.append(jsonData, withName: "data")
                    }, with: uploadUrl).responseDecodable(of: UploadResponse.self) { response in
                        if hud {
                            Loader.init().hide(delegate: vc)
                        }
                        print("Result: \(response)")
                        switch response.result {
                        case .success(let result):
                            let response = result.response
                            completion([:], response.success_message as NSString, true)
                        case .failure(let error):
                            let err = error.localizedDescription
                            print("Upload Failed: \(err)")
                            completion([:], err as NSString, false)
                            if alertMsg {
                                self.presentAlertWithTitle(title: "Error!", message: err, vc: vc)
                            }
                            break
                        }
                    }
            } else {
                self.presentAlertWithTitle(title: "Error!", message: "Please check network connectivity.", vc: vc)
            }