【发布时间】:2022-07-04 14:48:50
【问题描述】:
我有一个类来管理数据库,我在其中创建了将数据更新到特定实体的功能,但是当我使用分页调用 api 时,每次调用都会给我 50 个数据,在获取数据后,我将这些数据更新到我的表中,但是当时 UI 冻结由于将所有任务执行到主队列中,我已经看到了许多解决方案,但不完全了解如何通过不干扰 UI 任务进入后台队列和所有来做到这一点。
所以为什么我需要将所有进程都放入后台队列,即使不干扰 UI 任务,并且如果我的应用程序进入后台模式也可以工作。
我的应用程序委托文件我有这个:-
// MARK: - Core Data stack
lazy var persistentContainer: NSPersistentContainer = {
let container = NSPersistentContainer(name: "Name")
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
return container
}()
// MARK: - Core Data Saving support
func saveContext (completionBlock: @escaping ((Bool) -> ())) {
let context = persistentContainer.viewContext
if context.hasChanges {
do {
try context.save()
completionBlock (true)
} catch {
let nserror = error as NSError
completionBlock (false)
fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
}
}
}
我的数据库管理器有这个功能可以将数据保存在 coredata 中:-
func addUpdateState(stateArray: [StateInfo], completionBlock: @escaping ((Bool) -> ())) {
let localStateArray = self.getStatesData()
for state in stateArray {
let isContained = localStateArray.contains(where: {$0.id == state.id})
var stateDetail = StateMO()
if isContained == false {
//ADD STATE DATA
if let stateEntity = NSEntityDescription.entity(forEntityName: self.STATE_ENTITY, in: context) {
stateDetail = NSManagedObject (entity: stateEntity, insertInto: context) as! StateMO
}
} else {
//UPDATE STATE DATA
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: self.STATE_ENTITY)
fetchRequest.predicate = NSPredicate(format: "id == %@", state.id ?? "")
do {
let results = try context.fetch(fetchRequest)
if results.count != 0 {
stateDetail = results.first as! StateMO
}
} catch {
}
}
stateDetail.id = state.id
stateDetail.state_name = state.stateName
stateDetail.state_code = state.statecode
stateDetail.createdAt = state.createdAt
stateDetail.updatedAt = state.updatedAt
}
APP_DELEGATE.saveContext { result in
completionBlock (result)
}
}
我的 Api Manager 函数通过 alamofire 请求从服务器获取数据:-
func SyncStateList(with params: [String: Any], success: @escaping (_ result: Bool, _ message:String, _ response: [String: AnyObject]) -> () ,failure: @escaping (_ error: Error?) -> ()) {
let url = URLUtility.getURL(apiKey: ApiEndPoint.syncState)
let headers: HTTPHeaders = [
"token": currentUser?.token ?? ""
]
if Connectivity.isConnectedToInternet(){
AF.request(url, method: .post, parameters: params, encoding: JSONEncoding.default, headers: headers).responseJSON { response in
if response.response?.statusCode == 401
{
SVProgressHUD.dismiss()
showAlertMessage(title: self.unauthorizedMessage, "") {
LogoutClearEntireData()
}
} else if response.response?.statusCode == 200 {
if let json = response.value {
if let response = json as? [String: AnyObject] {
if response.success == true {
success(response.success,response.message,response)
} else {
success(false,response.message,response)
}
} else {
failure(response.error)
}
} else {
failure(response.error)
}
} else {
failure(response.error)
}
}.responseString { (responseString) in
printLog(responseString.description)
}
} else {
SVProgressHUD.dismiss()
showAlertMessage(title: "Unable to connect.", "Please check your internet connection.", complition: nil)
}
}
调用函数获取所有带分页的状态数据,并在开始同步时通过调用此函数存储到核心数据中:-
func SyncStateList(completionBlock: @escaping ((_ success:Bool) -> ())) {
let params: [String: Any] = ["date": lastModifiedDateForSyncState]
APIManager.shared.SyncStateList(with: params) { success, message, response in
if success == true {
if let dataResponse = response["data"] as? [String: Any] {
if let stateData = StateResponse(JSON: dataResponse) {
self.stateData = stateData
}
}
lastModifiedDateForSyncState = self.stateData?.lastModifiedDate ?? ""
if self.stateData?.isMoreRecordAvalilable == 1 {
DatabaseManager.shareInstance.addUpdateState(stateArray: self.stateData?.states ?? []) { result in
self.SyncStateList(completionBlock: completionBlock)
}
} else {
if self.stateData?.states.count != 0 {
DatabaseManager.shareInstance.addUpdateState(stateArray: self.stateData?.states ?? []) { result in
completionBlock(true)
}
} else {
completionBlock(true)
}
}
} else {
printLog(message)
completionBlock(false)
}
} failure: { error in
printLog(error?.localizedDescription ?? "")
completionBlock(false)
}
}
【问题讨论】:
标签: swift multithreading core-data alamofire