我在iOS中很新,想要和使用Alamofire。我想问下面的内容:如果已经处理了所有项目(在我的情况下是用户),如何调用一些完成块。完成块处于延迟块
StopsHandler.swift
func requestStopsForUser(user: User, completion: (result: RequestResult, json: JSON?) -> Void) {
alamofireManager?.request(.GET, "\(AppSettings.ApiURL)/v1/users/\(user.id)/stops.json", headers: ["Authorization": "Token token=\(user.apiKey)"]).responseJSON { response in
switch response.result {
case .Success:
if let value = response.result.value {
completion(result: .Success, json: JSON(value))
}
case .Failure(let error):
if error.code == NSURLErrorTimedOut {
completion(result: .TimedOut, json: nil)
} else {
completion(result: .ConnectionFailed, json: nil)
}
}
}
}
Main.swift
func fetchUsersAndStops(completion: (result: RequestResult) -> Void ) {
var allStopsToWrite = [[Stop]]() //for each user we have array of stops to write in model
requestAllUsers() { result, json in
switch result {
case .Success:
let users = self.usersFromJSON(json)
for (i, user) in users.enumerate() {
StopsHandler.sharedInstance.requestStopsForUser(user) { result, json in
print("i in = \(i)")
switch result {
case .Success:
defer {
let isLastUser = (i == users.count - 1)
if isLastUser {
try! self.realm.write(transactionBlock: {
for (index, stopsToWrite) in allStopsToWrite.enumerate() {
users[index].stops.appendContentsOf(stopsToWrite)
self.realm.add(users[index], update: true)
}},
completion: {
completion(result: .Success) //I want to call this completion when last user is already handled.
})
}
}
guard let json = json else {return}
let stops = StopsHandler.sharedInstance.stopsFromJSON(json)
let globalStops = self.realm.objects(Stop)
var stopsToWrite = [Stop]()
for stop in stops {
if globalStops.filter("id = '\(stop.id)'").first == nil {
stopsToWrite.append(stop)
if let currentUserId = self.currentUser?.id {
if currentUserId == user.id {
user.loggedIn = true
}
}
}
}
allStopsToWrite.append(stopsToWrite)
case .TimedOut:
completion(result: .TimedOut)
case .ConnectionFailed:
completion(result: .ConnectionFailed)
}
}
}
case .TimedOut:
completion(result: .TimedOut)
case .ConnectionFailed:
completion(result: .ConnectionFailed)
}
}
}
我假设我的代码在main_queue
中运行,我希望输出如下(我在服务器上有4个用户):
i in = 0
i in = 1
i in = 2
i in = 3
但我突然有了以下内容:
i in = 3
i in = 1
i in = 2
i in = 0
我不知道为什么。任何帮助都非常感谢!提前谢谢!
答案 0 :(得分:0)
asynchronously
未在主队列上运行。它运行.responseJSON
,但默认情况下main queue
将在dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(Double(0.2) * Double(NSEC_PER_SEC))), dispatch_get_main_queue(), {
// your code here.
})
上返回,以允许您更新UI。因此,您的输出不是您所期望的。
如果您希望它按顺序返回,则必须将请求包装在调度主队列中。
这样的事情:
@interface ViewController : UIViewController
{
CLLocationManager *locationManager;
}
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
CLLocationManager *locationManager = [[CLLocationManager alloc] init];
[locationManager startUpdatingLocation];
}
答案 1 :(得分:0)
由于Alarmofire在异步方法中调用请求。这就是为什么所有请求都是一次调用的原因,但响应时间对于所有请求都不一样。
要按顺序呼叫所有请求,您可以在上一次服务完成后致电服务。
由于我们遇到同样的问题所以我们确实使用了dispatch_block_t来执行序列任务。
MongoClient.connect(mongoUrl, (err, db) => {
assert.equal(null,err);
var collection_data = db.collection('threadContents').find();
collection_data.on('data', (doc) => {
var msg = doc.messages;
for (var variable in msg) {
console.log(msg);
}//forin(msg)
});//collection_data.on
});//mongo.connect
注意:这仅在您使用不同的呼叫获取每个用户信息时才有用。如果您在单个调用中获得所有用户信息,那么您只需要使用NSSortDescriptor对用户进行排序。
如果您遇到与执行序列任务相关的任何问题,可以在下面留言。