Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 如何使我的网络课程在Swift中通用?_Ios_Swift - Fatal编程技术网

Ios 如何使我的网络课程在Swift中通用?

Ios 如何使我的网络课程在Swift中通用?,ios,swift,Ios,Swift,在这里,我将数据提取为DataModel。但是我想让这个类成为泛型类,并自己传递模型,这样我就可以使用它来解析来自多个API的数据。有人能帮忙吗 导入基础 结构网络管理器{ func fetchData(url:String,completion:@escaping(DataModel?)->()){ 打印(“此处为Neeraj”) 让sessionURL=URL(字符串:URL) let session=URLSession(配置:。默认值) 让dataTask=session.dataTas

在这里,我将数据提取为DataModel。但是我想让这个类成为泛型类,并自己传递模型,这样我就可以使用它来解析来自多个API的数据。有人能帮忙吗

<代码>导入基础 结构网络管理器{ func fetchData(url:String,completion:@escaping(DataModel?)->()){ 打印(“此处为Neeraj”) 让sessionURL=URL(字符串:URL) let session=URLSession(配置:。默认值) 让dataTask=session.dataTask(带:sessionURL!){(数据、响应、错误)在 如果错误==nil{ 如果让safeData=data{ 如果让parsedData=self.parseData(数据:safeData){ 打印(“获取数据”) 完成(解析数据) } 否则{ debugPrint(“无法获取数据”) 完成(无) } } } 否则{ 打印(“数据任务中的错误为\(字符串(描述:错误))”) 完成(无) } } dataTask.resume() } func parseData(数据:数据)->数据模型{ let decoder=JSONDecoder() 做{ 让decodedData=try decoder.decode(DataModel.self,from:data) 返回解码数据 }抓住{ 打印(“分析数据时出错\(错误)”) 归零 } } }
您可以添加一个通用类型约束(称为
模型
),该约束符合
可解码
,如下所示:

struct NetworkManager{
func fetchData(url:String,completion:@escaping(Model?)->()){
让sessionURL=URL(字符串:URL)
let session=URLSession(配置:。默认值)
让dataTask=session.dataTask(带:sessionURL!){(数据、响应、错误)在
如果错误==nil{
如果让safeData=data{
做{
让decodedData=try JSONDecoder().decode(Model.self,from:safeData)
完成(解码数据)
}抓住{
打印(“分析数据时出错\(错误)”)
}
}否则{
debugPrint(“无法获取数据”)
完成(无)
}
}
否则{
打印(“数据任务中的错误为\(字符串(描述:错误))”)
完成(无)
}
}
dataTask.resume()
}
}
用法
struct SampleModel:可解码{
let name:String
}
NetworkManager().fetchData(url:){(数据:SampleModel?)位于
打印(数据)
}

您可以编写一个通用函数来获取如下数据:

    func fetchGenericData<T: Decodable>(urlString: String, completion: @escaping (T) -> ()) {
        let url = URL(string: urlString)
        URLSession.shared.dataTask(with: url!) { (data, resp, err) in
            if let err = err {
                print("Failed to fetch data:", err)
                return
            }
            
            guard let data = data else { return }
            
            do {
                let obj = try JSONDecoder().decode(T.self, from: data)
                completion(obj)
            } catch let jsonErr {
                print("Failed to decode json:", jsonErr)
            }
            }.resume()
    }
}
最后,您将解析数据并按如下方式打印:

Rob
Matt
Vadian

使用方便的
Result
类型,您可以编写一个非常小的泛型方法,成功时返回解码类型,失败时返回任何错误

func fetchData<T: Decodable>(urlString: String, completion: @escaping (Result<T,Error>) -> Void) {
    guard let url = URL(string: urlString) else { return } // or throw an error
    URLSession.shared.dataTask(with: url) { (data, _, error) in
        if let error = error { completion(.failure(error)); return }
        completion( Result{ try JSONDecoder().decode(T.self, from: data!) })
    }.resume()
}

DataModel
Codable
,因此您可能需要将其用于通用部件。但是你试过什么吗?您有一个非常简单的通用代码。如果需要,可以先将
parseData
代码放在fetch代码中,然后理解泛型,我不是在问使用泛型,而是在问如何自己传递数据模型,以便处理来自这个单一类的多个API。我应该如何调用它?我之前调用它就像self.networkManager.fetchData(url:url){(data)init给出的“无法推断泛型参数‘T’”错误我已经更新了我的答案,请检查@neerajgupta谢谢你的帮助@sonie。我知道了,我可以使用泛型来完成任务。也谢谢你的帮助@zeytin。我看到你在使用警卫,我喜欢你的方法。你写的代码如此干净。我认为这是一种更优雅的方法,因为它允许你访问错误这可能来自网络、操作系统或解码过程。此外,我不知道
init(catching:)
Result的初始值设定项存在:),尽管我倾向于将所有错误映射到自定义错误类型。
func fetchData<T: Decodable>(urlString: String, completion: @escaping (Result<T,Error>) -> Void) {
    guard let url = URL(string: urlString) else { return } // or throw an error
    URLSession.shared.dataTask(with: url) { (data, _, error) in
        if let error = error { completion(.failure(error)); return }
        completion( Result{ try JSONDecoder().decode(T.self, from: data!) })
    }.resume()
}
fetchData(urlString: "https://example.com/api") { (result : Result<MyModel,Error>) in
    switch result {
        case .success(let model): print(model)
        case .failure(let error): print(error)
    }
}