所以我有3个功能需要执行以下操作:
fetchNewMetaData()
使用Alamofire&amp ;;从网络服务器获取数据使用SyncDB将JSON响应与核心数据实体同步。fetchCurrentMetaObjects()
从Core Data Entity中获取对象,并将这些对象附加到[NSManagedObject]
数组中。applyLabels(label:UILabel, metaKey:String)
根据提供的metaKey将[NSManagedObject]
数组的值应用于指定的标签。以下是功能代码:
var items = [NSManagedObject]()
func fetchNewMetaData() {
let parameters: Parameters = ["email": email!, "password": password!]
let headers: HTTPHeaders = ["Content-Type": "application/x-www-form-urlencoded"]
Alamofire.request("https://mywebsite.com/Sync.php", method: .post, parameters: parameters, headers: headers).validate().responseJSON { response in
if let jsonResult = response.result.value {
let json = JSON(jsonResult)
let jsonData = json["data"]
print("JSON DATA : \(jsonData)")
let jsonString = jsonData.description
let stringData = jsonString.data(using: String.Encoding.utf8)
let serializedJSON = try! JSONSerialization.jsonObject(with: stringData!, options: []) as! [[String : Any]]
Sync.changes(serializedJSON, inEntityNamed: "Usermeta", dataStack: self.dataStack) { error in
self.fetchCurrentMetaObjects()
}
}
}
}
func fetchCurrentMetaObjects() {
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Usermeta")
request.sortDescriptors = [NSSortDescriptor(key: "remoteID", ascending: true)]
self.items = (try! dataStack.mainContext.fetch(request)) as! [NSManagedObject]
}
func applyLabels(label:UILabel, metaKey:String) {
for item in items as! [NSManagedObject] {
if let savedMetaKey = item.value(forKey: metaKey) as? String {
label.text = savedMetaKey
}
}
}
但是当我使用以下代码调用这些函数时,标签不会改变:
override func viewDidLoad() {
super.viewDidLoad()
self.fetchNewMetaData()
self.fetchCurrentMetaObjects()
DispatchQueue.main.async {
self.applyLabels(label: self.label, metaKey: "firstName")
}
}
我发现有几个线程在讨论SO上的调度组和队列但是所有这些线程都是基于Swift 2或Obj-C语法而没有应用于Swift 3.请问有什么问题在这里?我知道数据已保存到CoreData但看起来applyLabels()
在fetchcNewMetaData()
和fetchCurrentMetaObjects()
之前被调用了。
谢谢!
答案 0 :(得分:0)
fetchNewMetaData方法将在您收到alamofire响应之前返回。如果你在该方法中设置断点,你会注意到它在方法结束之前击中了最后一个},然后它进入Alamofire响应,然后它会返回并在片刻后点击Alamofire响应。
我假设您要按以下顺序调用方法? fetchNewMetaData - &gt;一旦得到回复 - &gt; fetchCurrentMetaObjects - &gt;完成后 - &gt;申请标签
如果是这种情况,请在Sync.change之后调用alamofire调用中的fetchCurrentMetaObjects,这意味着在获得响应之前不会调用fetchCurrentMetaObjects。
然后,在DispatchQueue.main.async中的fetchCurrentMetaObjects末尾调用applyLabels。
在你的viewDidLoad中,你应该调用的是fetchNewMetaData,然后它应该按顺序排列。让我知道这对你有用。