网络呼叫序列swift

af7jpaap  于 2022-12-17  发布在  Swift
关注(0)|答案(1)|浏览(116)

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

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

我必须接受ID从第一个输入的数字到第二个数字的注解(例如,从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
            }
        }
    }
}
gzszwxb4

gzszwxb41#

我不知道你的网络API到底做什么,这是一个现代的解决方案与斯威夫特并发。
同时加载立柱,然后连接,以保持顺序

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)
    }
}

相关问题