【问题标题】:Handling Back To Back HTTP Posts SWIFT 4.0处理背靠背 HTTP 帖子 SWIFT 4.0
【发布时间】:2018-04-01 10:48:11
【问题描述】:

我目前正在尝试从服务器获取一些数据。为此,我必须创建一个 JSON(req1) 对象并将其作为请求发送到第一个 API。然后,API 返回给我一个 JSON(res1)。从那个 JSON(res1) 中,我必须提取一些数据(很长,我们称之为 Data1)并创建另一个 JSON 对象(req2)并用它作为请求访问另一个 API 并等待响应(res2)。

现在,它是一个背靠背功能。当我调用第一个 API 时,需要很长时间才能响应,到那时,我的第二个 API 会被调用。因此,我从服务器收到一个错误。我该怎么办?

算法:

  1. 调用 API_A()
  2. 收到 JSON_A
  3. 提取 JSON_A 4.调用API_B(JASON_A.someparts)
  4. 收到 JSON_B
  5. 提取 JSON_B

下面是代码:

let json1 = JSON()
let json2 = JSON() //my final result

override func viewDidLoad() {
        super.viewDidLoad()
	    firstApiHit { () -> () in
            secondApiHit(jsonV: json1)
        }
    }

func firstApiHit(handleComplete:(()->())){
	let url1 = URL(string : firstApiURL) 
	let json: [String: String] = ["Data1:Data1Rest"]
	let jsonData = try? JSONSerialization.data(withJSONObject: json)
	json1 = httpPost(jsonData: jsonData!, url: url1!)  //hit to the first API!
	handleComplete()
}

func secondApiHit(jsonV : JSON){
	let url1 = URL(string : secondApiURL)
	var value = String()
	extractedValue = String(describing:jsonV["DataX"])
	var json = [String: String]()
	json = ["Data1":extractedValue]
	let jsonData = try? JSONSerialization.data(withJSONObject: json)
    let json2 = httpPost(jsonData: jsonData!, url: url2!) // my final result!
		//Need the json2 as the final Result!!
}
    
func httpPost(jsonData: Data, url: URL) -> JSON {
	if !jsonData.isEmpty {
		var request = URLRequest(url: url)
		request.httpMethod = "POST"
		request.httpBody = jsonData
		request.setValue("application/json", forHTTPHeaderField: "Content-Type")
		URLSession.shared.getAllTasks { (openTasks: [URLSessionTask]) in
									   print("open tasks: \(openTasks)")
									  }
		let task = URLSession.shared.dataTask(with: request) { data, response, error in
														  guard let data = data, error == nil else {   
															// check for fundamental networking error
															  print("error=\(String(describing: error))")
															  return
														  }
 		   	if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 {           
					// check for http errors
				print("statusCode should be 200, but is \(httpStatus.statusCode)")
				print("response = \(String(describing: response))")
			}
																  
			let jsonX = JSON(data: data) //extracting the data! 
		}	
    	task.resume()
	}
    return jsonM
}

【问题讨论】:

  • "因此,我从服务器收到一个错误" -- 为什么是 "thus"?什么原因?什么样的错误?
  • 你可能想看看 Alamofire。
  • 错误是,我无法从第一个响应中提取整个 JSON,因此,我的第二个请求不完整,导致第二个响应失败!失败,因为我得到一个 400 代码,而不是 200,所以我的 JSON 返回为空。
  • "httpPost()" 调用 URLSession.shared.dataTask() 这是异步的。所以jsonM 在调用“returns”时有 99.99% 的百分比为零。使用闭包。
  • @Larme 你能给我一个代码什么的吗?我在使用闭包时遇到问题!请问?

标签: ios swift api post swift4


【解决方案1】:

httpPost(...)URLSession.shared.dataTask(...) 完成之前返回,因为后者是异步运行的。

firstApiHit(...) 中,您不应调用handleComplete(),而应将其传递给httpPost(...)。您还需要将 JSON 作为参数传递。

override func viewDidLoad() {
    super.viewDidLoad()
    firstApiHit { json in
        secondApiHit(jsonV: json)
    }
}

func firstApiHit(handleComplete: JSON -> Void){
    ...
    json1 = httpPost(jsonData: jsonData!, url: url1!, handleComplete)
}

func httpPost(jsonData: Data, url: URL, responseHandler: (JSON) -> Void) {
    let task = URLSession.shared.dataTask(with: request) { data, response, error in
        ...                                   
        let jsonX = JSON(data: data)
        responseHandler(jsonX)
    }   
}

肯定需要学习如何使用闭包,更具体地说,是响应处理程序模式。否则你会一次又一次地陷入痛苦的世界中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-11-03
    • 1970-01-01
    • 1970-01-01
    • 2019-03-19
    • 2010-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多