You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift实现指定ID范围的批量网络请求并逐个展示评论

实现ID范围批量请求评论并逐个展示的方案

一、扩展API层,支持批量ID请求

先给现有API协议添加批量请求方法,同时用DispatchGroup管理多异步请求,既支持统一返回所有结果,也支持每请求完一个ID就回调进度(按需选择)。

修改协议与API实现

// 扩展协议,新增批量请求方法
protocol ApiImplementationProtocol {
    func getPosts(id: String, _ completionHandler: @escaping (Result<[Post], Error>)->())
    func getPostsInRange(from lower: Int, to upper: Int, _ completionHandler: @escaping (Result<[Post], Error>)->())
    // 带进度回调的批量请求(可选)
    func getPostsInRangeWithProgress(from lower: Int, to upper: Int, progressHandler: @escaping ([Post])->(), completionHandler: @escaping (Error?)->())
}

extension ApiImplementation: ApiImplementationProtocol {
    // 保留原有单个ID请求方法
    
    // 批量请求:统一返回所有评论
    func getPostsInRange(from lower: Int, to upper: Int, _ completionHandler: @escaping (Result<[Post], Error>)->()) {
        guard lower <= upper, lower > 0 else {
            completionHandler(.failure(NSError(domain: "InvalidRange", code: 0, userInfo: [NSLocalizedDescriptionKey: "ID范围不合法"])))
            return
        }
        
        let dispatchGroup = DispatchGroup()
        var allComments = [Post]()
        var requestError: Error?
        
        for id in lower...upper {
            dispatchGroup.enter()
            getPosts(id: String(id)) { result in
                defer { dispatchGroup.leave() }
                switch result {
                case .success(let comments):
                    allComments.append(contentsOf: comments)
                case .failure(let error):
                    requestError = error
                }
            }
        }
        
        dispatchGroup.notify(queue: .main) {
            if let error = requestError {
                completionHandler(.failure(error))
            } else {
                completionHandler(.success(allComments))
            }
        }
    }
    
    // 批量请求:每拿到一个ID的评论就回调进度
    func getPostsInRangeWithProgress(from lower: Int, to upper: Int, progressHandler: @escaping ([Post])->(), completionHandler: @escaping (Error?)->()) {
        guard lower <= upper, lower > 0 else {
            completionHandler(NSError(domain: "InvalidRange", code: 0, userInfo: [NSLocalizedDescriptionKey: "ID范围不合法"]))
            return
        }
        
        let dispatchGroup = DispatchGroup()
        var requestError: Error?
        
        for id in lower...upper {
            dispatchGroup.enter()
            getPosts(id: String(id)) { result in
                defer { dispatchGroup.leave() }
                switch result {
                case .success(let comments):
                    DispatchQueue.main.async {
                        progressHandler(comments) // 回到主线程更新UI
                    }
                case .failure(let error):
                    requestError = error
                }
            }
        }
        
        dispatchGroup.notify(queue: .main) {
            completionHandler(requestError)
        }
    }
}

二、处理TextField输入验证与UI展示

在ViewController中先验证用户输入的合法性,再调用API请求,最后实现逐个展示评论的逻辑:

// 假设两个输入框:lowerTextField(下限)、upperTextField(上限)
@IBAction func fetchCommentsTapped(_ sender: UIButton) {
    guard let lowerText = lowerTextField.text, let lower = Int(lowerText),
          let upperText = upperTextField.text, let upper = Int(upperText) else {
        showAlert(message: "请输入有效的数字ID")
        return
    }
    
    guard lower <= upper, lower > 0 else {
        showAlert(message: "ID范围不合法,下限需≤上限且大于0")
        return
    }
    
    let api = ApiImplementation(networkService: YourNetworkService())
    
    // 方式一:统一拿到所有评论后逐个展示
    api.getPostsInRange(from: lower, to: upper) { result in
        switch result {
        case .success(let allComments):
            self.displayCommentsOneByOne(allComments)
        case .failure(let error):
            self.showAlert(message: "请求失败:\(error.localizedDescription)")
        }
    }
    
    // 方式二:每拿到一个ID的评论就立即展示
    /*
    api.getPostsInRangeWithProgress(from: lower, to: upper) { comments in
        self.displayComments(comments)
    } completionHandler: { error in
        if let error = error {
            self.showAlert(message: "请求中断:\(error.localizedDescription)")
        } else {
            self.showAlert(message: "所有评论加载完成")
        }
    }
    */
}

// 逐个展示评论的UI逻辑示例(可替换为你的实际UI更新代码)
private func displayCommentsOneByOne(_ comments: [Post]) {
    var index = 0
    let timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { [weak self] timer in
        guard let self = self, index < comments.count else {
            timer.invalidate()
            return
        }
        let comment = comments[index]
        // 示例:打印评论标题,实际可添加到TableView/Label等
        print("展示评论:\(comment.title)")
        index += 1
    }
    timer.fire()
}

private func displayComments(_ comments: [Post]) {
    // 展示单ID下的所有评论
    comments.forEach { comment in
        print("实时展示评论:\(comment.title)")
    }
}

private func showAlert(message: String) {
    let alert = UIAlertController(title: "提示", message: message, preferredStyle: .alert)
    alert.addAction(UIAlertAction(title: "确定", style: .default))
    present(alert, animated: true)
}

三、注意事项

  • 模型命名Post与实际请求的comments不匹配,建议改为Comment避免混淆,同时确保模型结构和接口返回的JSON字段完全对应。
  • 可给批量请求添加重试、超时逻辑,避免单个请求失败导致整个任务中断。
  • 限制最大请求范围(比如最多一次请求20个ID),避免频繁请求给服务器造成压力。

内容的提问来源于stack exchange,提问作者Eugene.IOS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 22:35:49