网络调用顺序 swift

sequence of network calls swift

提问人:eleoperdev9 提问时间:12/13/2022 更新时间:12/14/2022 访问量:86

问:

我必须 textFields,第一个输入(下限)和第二个(上限),在我输入数字的文本字段后,我必须对服务提出请求:

https://jsonplaceholder.typicode.com/guide/

我必须使用从第一个输入的数字到第二个输入的数字(例如,从 1 到 10)进行注释

您不能在查询中输入范围,只能输入一个标识符,例如:

https://jsonplaceholder.typicode.com/posts/1/comments

如何使用范围实现一系列查询,我逐个显示注释?

我需要有关网络调用构建顺序的帮助,现在我有一个简单的请求:

enum EndPoint {
    var pass: String {
        switch self {
        case.post(let id):
            return "posts/" + id + "/comments"
        }
    }
    
    case post(String)
}

protocol ApiImplementationProtocol {
    func getPosts(id: String, _ completionHandler: @escaping (Result<[Post], Error>)->())
}

class ApiImplementation {
    private let networkService: ApiServiceProtocol
    fileprivate let decoder = JSONDecoder()
    
    init (networkService: ApiServiceProtocol) {
        self.networkService = networkService
    }
    private let base = "https://jsonplaceholder.typicode.com/"
}

extension ApiImplementation: ApiImplementationProtocol {
    
    func getPosts(id: String, _ completionHandler : @escaping (Result<[Post], Error>)->()) {
        
        let part = EndPoint.post(id.description).pass
               guard let url = URL(string: base + part) else {
                   fatalError()
               }
        let request = URLRequest(url: url)
        self.networkService.request(request: request) { [unowned self] (result) in
            switch result {
            case .success(let data) :
                guard let posts = try? self.decoder.decode([Post].self, from: data) else {
                    return
                }
                completionHandler(.success(posts))
                break
            case .fail(let error):
                _ = error
    
                break
            }
        }
    }
}
SWIFT 多线程 请求 序列

评论

0赞 Community 12/14/2022
请澄清您的具体问题或提供其他详细信息,以准确说明您的需求。正如目前所写的那样,很难确切地说出你在问什么。

答:

0赞 vadian 12/14/2022 #1

我不知道你的网络 API 到底是做什么的,这是一个具有 Swift 并发的现代解决方案。

这些帖子同时加载,稍后加入以保留顺序

struct Post : Decodable {
    let postId: Int
    let id: Int
    let name, email, body: String
}

func getPosts(from: Int, to: Int) async throws -> [Post]  {
    let range = from...to
    let allPosts = try await withThrowingTaskGroup(of: (Int, [Post]).self,
                                                   returning: [Int: [Post]].self,
                                                   body: { taskGroup in
        
        for index in range {
            taskGroup.addTask {
                let url = URL(string: "https://jsonplaceholder.typicode.com/posts/\(index)/comments")!
                let (data, _) = try await URLSession.shared.data(from: url)
                let posts = try JSONDecoder().decode([Post].self, from: data)
                return (index, posts)
            }
        }
        
        var childTaskResults = [Int: [Post]]()
        for try await (key, value) in taskGroup {
            childTaskResults[key] = value
        }
        return childTaskResults
    })
    let indices = allPosts.keys.sorted()
    return indices.map{ allPosts[$0]! }.flatMap{$0}
}

并调用函数

Task {
    do {
        let posts = try await getPosts(from: 1, to: 3)
        print(posts.map(\.body))
    } catch {
        print(error)
    }
}