我需要在我的coredata中同步web数据库,我为此执行服务api调用。我正在使用Alamofire
Swift 3
。有23个api调用,在不同的coredata实体中提供近24k行。
我的问题:这些api调用会阻止UI一分钟,这是用户等待很长时间。
我尝试使用DispatchQueue
并在后台线程中执行任务,但没有任何效果。这就是我尝试的方式:
let dataQueue = DispatchQueue.init(label: "com.app.dataSyncQueue")
dataQueue.async {
DataSyncController().performStateSyncAPICall()
DataSyncController().performRegionSyncAPICall()
DataSyncController().performStateRegionSyncAPICall()
DataSyncController().performBuildingRegionSyncAPICall()
PriceSyncController().performBasicPriceSyncAPICall()
PriceSyncController().performHeightCostSyncAPICall()
// Apis which will be used in later screens are called in background
self.performSelector(inBackground: #selector(self.performBackgroundTask), with: nil)
}
来自DataSyncController的API调用:
func performStateSyncAPICall() -> Void {
DataSyncRequestManager.fetchStatesDataWithCompletionBlock {
success, response, error in
self.apiManager.didStatesApiComplete = true
}
}
DataSyncRequestManager代码:
static func fetchStatesDataWithCompletionBlock(block:@escaping requestCompletionBlock) {
if appDelegate.isNetworkAvailable {
Util.setAPIStatus(key: kStateApiStatus, with: kInProgress)
DataSyncingInterface().performStateSyncingWith(request:DataSyncRequest().createStateSyncingRequest() , withCompletionBlock: block)
} else {
//TODO: show network failure error
}
}
DataSyncingInterface代码:
func performStateSyncingWith(request:Request, withCompletionBlock block:@escaping requestCompletionBlock)
{
self.interfaceBlock = block
let apiurl = NetworkHttpClient.getBaseUrl() + request.urlPath!
Alamofire.request(apiurl, parameters: request.getParams(), encoding: URLEncoding.default).responseJSON { response in
guard response.result.isSuccess else {
block(false, "error", nil )
return
}
guard let responseValue = response.result.value else {
block (false, "error", nil)
return
}
block(true, responseValue, nil)
}
}
我知道很多类似的问题已经发布在Stackoverflow上,并且大多数建议使用GCD或Operation Queue,尽管尝试DispatchQueues
对我不起作用。
我做错了吗? 我怎么能不阻止UI并同时执行api调用?
答案 0 :(得分:2)
您可以执行此操作以在后台线程上运行:
DispatchQueue.global(qos: .background).async {
// Do any processing you want.
DispatchQueue.main.async {
// Go back to the main thread to update the UI.
}
}
答案 1 :(得分:0)
DispatchQueue管理工作项的执行。提交到队列的每个工作项都在系统管理的线程池上处理。
我通常将NSOperationQueue与Alamofire一起使用,但概念类似。设置异步队列时,允许独立于主(UI)线程执行工作,以便您的应用程序不会冻结(拒绝用户输入)。这项工作仍然需要很长时间,但是你的程序在等待完成时不会阻塞。
你真的只把一个项目放入队列。
您只需要向队列添加一次,因此所有这些"执行"呼叫等待前一个完成。如果同时运行它们是安全的,则需要将它们中的每一个分别添加到队列中。有多种方法可以做到这一点,但每次调用.async {}时,底线就是将一个项目添加到队列中。
dataQueue.async {
DataSyncController().performStateSyncAPICall()
}
dataQueue.async {
DataSyncController(). performRegionSyncAPICall l()
}