Swift 4 上的几个相互依赖的 JSON 请求
Posted
技术标签:
【中文标题】Swift 4 上的几个相互依赖的 JSON 请求【英文标题】:Several co-dependent JSON requests on Swift 4 【发布时间】:2018-09-19 15:11:47 【问题描述】:我正在重构我之前编写的代码,我使用 Alamofire 下载一些 Json 文件。 第一个请求是直截了当的。我提出请求,得到响应,然后解析它并将其存储在 Realm 中。这里没问题。直截了当的东西。 第二个请求有点棘手,因为我需要从第一个 JSON 请求中检索到的几个 ID。
我对该问题的解决方案是首先在具有 Alamofire 请求的函数上创建一个 Completion 处理程序:
func requestData(httpMethod: String, param: Any?, CallType : String, complition: @escaping (Bool, Any?, Error?) -> Void)
我的想法是使用 Completion 等待 Alamofire 响应完成,然后启动新请求。事实证明这也不起作用。
我能够通过为完成添加延迟来实现这一目标。
DispatchQueue.main.asyncAfter(deadline: .now() + 4)
它确实有效,但由于多种原因远非一个好的做法,我想用更智能的东西来重构它。
我的问题:
1) 在同一个函数上发出多个 JSON 请求的最佳方式是什么?一种正确等待第一个开始第二个的方法,依此类推? 2) 现在,我调用一个函数来请求第一个 JSON,并在调用中间发出第二个请求。在我看来,我将第一个请求挂得太久,等待所有请求完成然后完成第一个请求。我认为这不是一个好习惯
这是完整的代码。感谢帮助
@IBAction func getDataButtonPressed(_ sender: Any)
requestData(httpMethod: "GET", param: nil, CallType: "budgets") (sucess, response, error) in
if sucess
print("ready")
DispatchQueue.main.asyncAfter(deadline: .now() + 4)
accounts = realm.objects(Account.self)
requestAccounts()
DispatchQueue.main.asyncAfter(deadline: .now() + 4)
users = realm.objects(User.self)
requestUser()
func requestData(httpMethod: String, param: Any?, CallType : String, complition: @escaping (Bool, Any?, Error?) -> Void)
let url = "https://XPTO.com/v1/\(CallType)"
guard let urlAddress = URL(string: url) else return
var request = URLRequest(url: urlAddress)
request.httpMethod = httpMethod
request.addValue("application/json", forHTTPHeaderField: "accept")
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("Bearer appKey", forHTTPHeaderField: "Authorization")
if param != nil
guard let httpBody = try? JSONSerialization.data(withJSONObject: param!, options:[]) else return
request.httpBody = httpBody
Alamofire.request(request).responseJSON (response) in
let statusCode = response.response?.statusCode
print("Status Code \(statusCode!)")
jsonData = try! JSON(data: response.data!)
complition(true, jsonData, nil)
if httpMethod == "GET"
saveJsonResponse(jsonData: jsonData, CallType: CallType)
func requestAccounts()
var count = accounts.count
while count != 0
let account = accounts[0]
RealmServices.shared.delete(account)
count -= 1
let numberOfBugdets = budgets.count
for i in 0...numberOfBugdets - 1
requestData(httpMethod: "GET", param: nil, CallType: "/budgets/\(budgets[i].id)/accounts") (sucess, response, error) in
print("accounts downloaded")
let numberOfAccounts = jsonData["data"]["accounts"].count
for j in 0...numberOfAccounts - 1
let realm = try! Realm()
do
try realm.write
// Code to save JSON data to Realm
realm.add(newAccount)
catch
print("something")
func requestUser()
var count = users.count
while count != 0
let user = users[0]
RealmServices.shared.delete(user)
count -= 1
requestData(httpMethod: "GET", param: nil, CallType: "user") (success, response, error) in
print("User data downloaded")
let realm = try! Realm()
do
try realm.write
// Code to save JSON data to Realm
realm.add(newUser)
catch
print("something")
func saveJsonResponse(jsonData: JSON, CallType: String)
case "budgets":
var count = budgets.count
while count != 0
let budget = budgets[0]
RealmServices.shared.delete(budget)
count -= 1
let numberOfBudgets = jsonData["data"]["budgets"].count
for i in 0...numberOfBudgets - 1
// Code to save JSON data to Realm
RealmServices.shared.create(newBudget)
【问题讨论】:
为什么不在2个函数中分开,当你得到id时使用完成来调用第二个? 【参考方案1】:我推荐 completionHandlers 在这种情况下。
这就是你的代码如何实现和使用它,尝试理解它并在你的代码中实现它。
//CompletionHandlers
func firstOperation(completionHandler: @escaping (_ id: String) -> Void)
//preform alamoFire and in .response call completionHandler and pass it the id
completionHandler("10")
func buttonClicked ()
firstOperation (id) in
secondFunction(completionHandler: (data) in
// your data
)
func secondFunction(completionHandler: @escaping (_ data: String) -> Void)
//preform alamoFire and in .response call completionHandler and pass it the id
completionHandler("some Data")
这应该会让你更好地理解如何实现它,CompletionHandlers 很强大
特别是在处理此类情况时,您必须执行依赖于其他操作结果的操作,并且在网络中我们无论如何都无法预测操作的时间。
阅读有关 completionHandlers 的更多信息here
【讨论】:
以上是关于Swift 4 上的几个相互依赖的 JSON 请求的主要内容,如果未能解决你的问题,请参考以下文章