无法转换类型“字典<String, Any>?”的值?到预期的参数类型“数据”

Posted

技术标签:

【中文标题】无法转换类型“字典<String, Any>?”的值?到预期的参数类型“数据”【英文标题】:Cannot convert value of type 'Dictionary<String, Any>?' to expected argument type 'Data' 【发布时间】:2018-04-14 12:44:43 【问题描述】:

我还是 swift 新手,我正在尝试获取 json 数据并将其作为我创建的对象传递给下一个视图。但是,我收到此错误 无法转换“字典”类型的值?当我尝试使用解码器类时,预期的参数类型“数据”。我不知道该怎么做才能解决它。我已尝试在完成处理程序中将 Dictionary?' 更改为 Data,但仍然出现错误。

这是我的代码:

服务电话

    class ServiceCall: NSObject, ServiceCallProtocol, URLSessionDelegate 



    let urlServiceCall: String?
    let country: String?
    let phone: String?
     var search: SearchResultObj?

    init(urlServiceCall: String,country: String, phone: String)
        self.urlServiceCall = urlServiceCall
        self.country = country
        self.phone = phone
    


    func fetchJson(request: URLRequest, customerCountry: String, mobileNumber: String, completion: ((Bool, Dictionary<String, Any>?) -> Void)?)

        let searchParamas = CustomerSearch.init(country: customerCountry, phoneNumber: mobileNumber)
        var request = request
        request.httpMethod = "POST"
        request.httpBody = try?  searchParamas.jsonData()
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")

        let session = URLSession.shared
        let task = session.dataTask(with: request, completionHandler:  data, response, error -> Void in
            do 
                let json = try JSONSerialization.jsonObject(with: data!) as! Dictionary<String, Any>
                let status = json["status"] as? Bool
                if status == true 
                    print(json)
                else
                    print(" Terrible failure")
                
             catch 
               print("Unable to make an api call")
            
        )

        task.resume()

    


  

SearchViewModel

func searchDataRequested(_ apiUrl: String,_ country: String,_ phone:String) 

    let service = ServiceCall(urlServiceCall: apiUrl, country: country, phone: phone)
    let url = URL(string: apiUrl)
    let request = URLRequest(url: url!)
    let country = country
    let phone = phone

    service.fetchJson(request: request, customerCountry: country, mobileNumber: phone)
     (ok, json) in
        print("CallBack response : \(String(describing: json))")
        let decoder = JSONDecoder()
        let result = decoder.decode(SearchResultObj.self, from: json)

        print(result.name)
        // self.jsonMappingToSearch(json as AnyObject)

    

新错误:

【问题讨论】:

尝试发布您尝试解码的 JSON 对不起,我不明白 【参考方案1】:

您将反序列化 JSON 两次,但无法正常工作。

不是返回Dictionary而是返回Data,这个错误会导致错误,但还有更多问题。

func fetchJson(request: URLRequest, customerCountry: String, mobileNumber: String, completion: (Bool, Data?) -> Void)  ...

然后将数据任务改为

let task = session.dataTask(with: request, completionHandler:  data, response, error -> Void in

    if let error = error  
        print("Unable to make an api call", error)
        completion(false, nil)
        return 
    
    completion(true, data)
)

和服务调用

service.fetchJson(request: request, customerCountry: country, mobileNumber: phone)  (ok, data) in
    if ok 
        print("CallBack response :", String(data: data!, encoding: .utf8))
        do 
            let result = try JSONDecoder().decode(SearchResultObj.self, from: data!)
            print(result.name)
            // self.jsonMappingToSearch(json as AnyObject)
         catch  print(error) 
    

你必须在ServiceCall中采用Decodable

class ServiceCall: NSObject, ServiceCallProtocol, URLSessionDelegate, Decodable  ...

此外,我强烈建议将类模型与代码分开以检索数据。

【讨论】:

谢谢你这个工作有你的答案有一些错别字但它工作。 我编辑了答案并将完成处理程序设为非可选,因为它总是会被调用。 Bool 参数没用。只需传递Data 并打开it let data = data 以检查它是否成功。我会在完成时传递Error? 而不是Bool completion: (Data?, Error?) -&gt; () 并调用completion(data, error) @LeoDabus 我知道。我什至会传递一个带有关联值的枚举,但我不想混淆 OP【参考方案2】:

会话任务返回的数据可以用JSONSerialization序列化,也可以用JSONDecoder解码

 let task = session.dataTask(with: request, completionHandler:  data, response, error -> Void in

任何一个

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

let result = try  decoder.decode([item].self,data!)

decode 方法的第二个参数需要Data 类型的参数而不是Dictionary

您只需编辑 fetchJson 的完成以返回 Bool,Data 而不是 Bool,Dictionary,并从中删除 JSONSerialization 代码

【讨论】:

去掉逗号

以上是关于无法转换类型“字典<String, Any>?”的值?到预期的参数类型“数据”的主要内容,如果未能解决你的问题,请参考以下文章

无法转换“Foo!”类型的值到预期的参数类型'Foo!'

无法将类型“()”的值转换为预期的参数类型“字符串”

无法将类型为“System.Collections.Generic.List`1[EPMS.Domain.SingleItem]”的对象强制转换为类型“EPMS

无法转换类型的值'(数据:CMAccelerometerData!,错误:NSError!)

无法将 [Struct] 类型的值快速转换为 [string] 类型

无法转换类型“(_)-> Void?”的值到预期的参数类型'(() - > Void)?