Json响应在swift中加载非常慢

Json response loading very slowly in swift

提问人:Swift 提问时间:11/13/2023 最后编辑:Phil DukhovSwift 更新时间:11/14/2023 访问量:51

问:

我有全速互联网,邮递员数据加载速度很快,但我的代码响应在 5 分钟后出现,为什么?我哪里错了?我尝试了所有可能的方法来快速显示数据,但仍然面临问题。

以下代码将在 5 分钟后显示响应。最初我以为没有数据,但 5 分钟后数据显示。我哪里错了?

class APINetworkManagerMultipart: NSObject {
    static let sharedInstance = APINetworkManagerMultipart()
    
    fileprivate override init() {
        super.init()
    }
    func serviceCallWithMultipartFormData<T: Codable>(
        url: URL,
        headers: [String: String]?,
        parameters: [String: Any],
        completion: @escaping (Result<T, Error>) -> Void
    ) {
        var request = URLRequest(url: url)
        request.httpMethod = "POST"
        let token = "Bearer mytoken"
        request.setValue(token, forHTTPHeaderField: "Authorization")
        
        let boundary = "Boundary-\(UUID().uuidString)"
        request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
        
        let body = NSMutableData()
        
        for (key, value) in parameters {
            if let stringValue = value as? String {
                body.append("--\(boundary)\r\n".data(using: .utf8)!)
                body.append("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n".data(using: .utf8)!)
                body.append("\(stringValue)\r\n".data(using: .utf8)!)
            }
            else if let data = value as? Data {
                
                body.append("--\(boundary)\r\n".data(using: .utf8)!)
                body.append("Content-Disposition: form-data; name=\"\(key)\"; filename=\"file\"\r\n".data(using: .utf8)!)
                body.append("Content-Type: application/octet-stream\r\n\r\n".data(using: .utf8)!)
                body.append(data)
                body.append("\r\n".data(using: .utf8)!)
            }
        }
        
        body.append("--\(boundary)--\r\n".data(using: .utf8)!)
        request.httpBody = body as Data
        
        if let customHeaders = headers {
            for (key, value) in customHeaders {
                request.setValue(value, forHTTPHeaderField: key)
            }
        }
        DispatchQueue.global(qos: .background).async {
            
            let task = URLSession.shared.dataTask(with: request) { data, response, error in
                if let error = error {
                    completion(.failure(error))
                    return
                }
                guard let data = data else {
                    completion(.failure(error!))
                    return
                }
                do {
                    let decodedData = try JSONDecoder().decode(T.self, from: data)
                    completion(.success(decodedData))
                } catch {
                    completion(.failure(error))
                }
            }
            task.resume()
        }
    }
} 

并在视图控制器中使用这样的服务调用

func genericFormdataCall(){
    let urlStr = URL(string: "https://prg-name/dev/api/student/edit-profile")!
    let parameters: [String: Any] = [
        "dob": "2005-07-24",
        "name": "Student",
        "gender": "M",
        "school_location": "TestLocation",
        "school_name": "K V",
        "grade": "12th grade",
        "student_bio": "I am a student",
        "profile_pic": nil
    ] as! [String : Any]
    
    DispatchQueue.global().async {
        
        APINetworkManagerMultipart.sharedInstance.serviceCallWithMultipartFormData(url: urlStr, headers: nil, parameters: parameters) { (result: Result<MultipartModel, Error>) in
            switch result {
            case .success(let response):
                // Handle the successful response
                self.formdataResponse = response
                print("Response: \(response)")
            case .failure(let error):
                // Handle the error
                print("Error: \(error)")
            }
        }
    }
}
JSON Swift Web 服务 泛型 响应

评论

0赞 lorem ipsum 11/13/2023
看起来您正在移动到后台两次(降低优先级)。查看 async/await。
0赞 burnsi 11/13/2023
不需要这些调用。您可以删除它们。from 将在后台线程 allready 上运行。DispatchQueuedataTaskURLSession
0赞 Larme 11/14/2023
Content-Type: application/octet-stream?不应该是吗? ?零图像?Content-Type: image/png"profile_pic": nil

答:

0赞 son 11/13/2023 #1

我已经尝试了您的最小代码。似乎问题是 在 .我认为不能这样推断。我添加了一个名为表示响应类型的参数。然后它按预期工作。Resultresponse

func serviceCallWithMultipartFormData<T: Codable>(
        url: URL,
        headers: [String: String]?,
        parameters: [String: Any],
        response: T.Type,
        completion: @escaping (Result<T, Error>) -> Void
) {
    ...
}

//How to use
serviceCallWithMultipartFormData(..., response: MultipartModel.self)

请注意,您应该删除此不必要的代码。该函数已异步运行。如果您在 UI 中使用数据,则只需在主线程上处理完成。Dispatqueue.globaldataTask