阿拉莫菲尔 调用类方法“jsonObject”时没有完全匹配项

Alamofire No exact matches in call to class method 'jsonObject'

提问人:user979331 提问时间:8/23/2023 更新时间:8/23/2023 访问量:80

问:

我像这样使用 Alamofire:

let headers: HTTPHeaders = [
            .accept("application/json")
        ]

let credential = URLCredential(user: "username", password: "p@ssword", persistence: .none)
        
        AF.request(webservice, headers: headers).authenticate(with: credential).responseDecodable(of: Dictionary<String, Dictionary<String, Any>>.self) { response in
            print(response)
        }

但是我收到此错误:

类型“Any”不能符合“Decodable”

我刚刚切换到 Alamofire,我的调用正在工作,但格式化数据不是,我使用的方式获取数据如下:

URLSession.shared.dataTask(with: url!, completionHandler: {
            (data, response, error) in
            
            if(error != nil){
                
                completion(false)
                
            }else{
                
                do{
                    
                    let json = try JSONSerialization.jsonObject(with: data!, options:.allowFragments) as! Dictionary<String, Dictionary<String, Any>>
                    
                    OperationQueue.main.addOperation({
                        
                        completion(json)
                        
                    })
                    
                }catch let error as NSError{
                    
                    print(error)
                    completion(false)
                    
                }
            }
            
        }).resume()

更新

我把我的电话改成了这个:

AF.request(webservice, headers: headers).authenticate(with: credential).response { response in
            print(response)
            do{
                let json = try JSONSerialization.jsonObject(with: response!, options:.allowFragments) as! Dictionary<String, Dictionary<String, Any>>
            }catch let error as NSError{
            }
        }

但是我现在收到此错误:在调用类方法“jsonObject”时没有完全匹配项

iOS版 斯威夫特 阿拉莫火

评论

0赞 Larme 8/23/2023
response!不是对象,这就是为什么......是,或者,我记不清了......Dataresponse.dataresponse.response.data
0赞 Larme 8/23/2023
不相关,但毫无用处,因为根据您的代码,您期望一个 ,而不仅仅是一个 String、Int...有什么理由不使用吗?并且可以只是.options:.allowFragmentsDictionaryCodablecatch let error as NSErrorcatch
0赞 user979331 8/23/2023
@Larme response.data奏效了!谢谢!
0赞 Jon Shier 8/24/2023
停止手动解码 JSON,并使用正确的类型。responseDecodable

答:

1赞 Larme 8/23/2023 #1

编译器错误是

No exact matches in call to class method 'jsonObject'

所以这意味着,有一个看起来很相似的静态方法,但它并不相同。JSONSerialization

因此,当您遇到此问题时,通常是错别字或错误类型。 就你而言,这是糟糕的类型。

让我们首先检查 . 您可能需要先对导致错误的行进行注释。 将鼠标悬停在 上,按住 Option 键(光标变换为问号),然后单击 。 您将获得其类型:。responseresponseresponseAFDataResponse<Data?>

现在,让我们看看 JSONSerialization 文档,它有这两个方法(我强烈猜你想要第一个):

class func jsonObject(with: Data, options: JSONSerialization.ReadingOptions) -> Any

class func jsonObject(with: InputStream, options: JSONSerialization.ReadingOptions) -> Any

看到问题了吗?

Data != AFDataResponse<Data?>

要从 访问对象,请使用:Dataresponseresponse.data

let json = try JSONSerialization.jsonObject(with: response.data!, options:.allowFragments) as! Dictionary<String, Dictionary<String, Any>>

不相关,但由于这是一个 SO 问题,我们倾向于经常严格地讨论这个问题,但我注意到了一些事情,我不希望有人在学习时复制它们。

现在,您正在使用强制解包(使用 ),如果有问题:为零,不是 ,它将崩溃,仅供参考。!response.datajsonDictionary<String, Dictionary<String, Any>>

catch let error as NSError可以替换为catch

options:.allowFragments是不需要的。要需要,JSON 只需是 、 或 .换句话说,在顶层,它不是 an 也不是 .BoolStringNumberArrayDictionary

您可能还想检查响应是否成功,否则整个响应可能会有所不同,然后,它可能不是响应,并且会崩溃。我们可以想象用 HTML 错误代码响应 500 错误,你会让它崩溃。Dictionary<String, Dictionary<String, Any>>as!

所以,我会这样写:

AF.request(webservice, headers: headers).authenticate(with: credential).response { response in
    print(response)
    
    switch response.result {
    case .success(let data):
        do {
            guard let data = data else { print("Success, but empty response"); return }
            let json = try JSONSerialization.jsonObject(with: data)
            guard let jsonDict = json as? [String: [String: Any]] else {
                print("JSON is not a [String: [String: Any]]: \(json)")
                return
            }
            //Use jsonDict
        } catch {
            print("Error while decoding: \(error)")
        }
    case .failure(let error):
        print("Error: \(error)")
    }
}