Ios 阿拉莫菲尔-如何处理完成块?
我对iOS非常陌生,想要并使用Alamofire。我想问以下问题:当所有项目(在我的例子中是用户)都已处理时,如何调用一些完成块。完成块位于延迟块中 StopsHandler.swiftIos 阿拉莫菲尔-如何处理完成块?,ios,swift,alamofire,Ios,Swift,Alamofire,我对iOS非常陌生,想要并使用Alamofire。我想问以下问题:当所有项目(在我的例子中是用户)都已处理时,如何调用一些完成块。完成块位于延迟块中 StopsHandler.swift func requestStopsForUser(user: User, completion: (result: RequestResult, json: JSON?) -> Void) { alamofireManager?.request(.GET, "\(AppSettings.ApiUR
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)
}
}
}
}
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.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)
}
}
}
}
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 = 3
i in = 1
i in = 2
i in = 0
我不知道为什么。非常感谢您的帮助!提前谢谢
Alamofire.request
未在主队列上运行。它异步运行
,但默认情况下,主队列上的.responseJSON
将返回以允许您更新UI。因此,您的输出不是您所期望的
如果希望它按顺序返回,则必须将请求包装在调度主队列中
大概是这样的:
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(Double(0.2) * Double(NSEC_PER_SEC))), dispatch_get_main_queue(), {
// your code here.
})
Alamofire.request
未在主队列上运行。它异步运行
,但默认情况下,主队列上的.responseJSON
将返回以允许您更新UI。因此,您的输出不是您所期望的
如果希望它按顺序返回,则必须将请求包装在调度主队列中
大概是这样的:
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(Double(0.2) * Double(NSEC_PER_SEC))), dispatch_get_main_queue(), {
// your code here.
})
因为Alarmofire正在异步方法中调用请求。这就是为什么所有的请求都是一次调用的,但是对于所有的请求,响应时间都不一样
若要按顺序调用所有请求,可以在前一个服务完成后调用服务
由于我们面临同样的问题,所以我们确实使用了调度块来执行序列任务
- (void)fetchAllUserAndStopWithCompletion:(void(^)(id resultResponse, BOOL isComplete))completion {
// Step 1: Define default parameters and limits.
__block NSInteger totalNumberOfUser = 4;
__block NSInteger currentRequest = 0;
__block dispatch_block_t t_request;
dispatch_block_t request = [^{
// Step 2: Fetch User information for currentRequest id.
[UserRequest fetchUserRequestWithId:<UserId or Any Unique Id>
successBlock:^(id resultResponse, NSError *error) {
currentRequest += 1;
// Step 3: Check for remaining request. If request is remaining then call ’t_request()’.
if (currentRequest < totalNumberOfUser) {
// Request Remaining
if (completion) {
id response = (!error)?resultResponse:nil;
completion(response, NO);
}
t_request();
}
else {
// All Request Completed
if (completion) {
id response = (!error)?resultResponse:nil;
completion(response, YES);
}
}
}];
} copy];
t_request = request;
request();
}
-(void)fetchAllUserAndStopWithCompletion:(void(^)(id resultResponse,BOOL isComplete))完成{
//步骤1:定义默认参数和限制。
__块NSInteger totalNumberOfUser=4;
__块NSInteger currentRequest=0;
__阻塞调度请求;
调度阻止请求=[^{
//步骤2:获取currentRequest id的用户信息。
[UserRequest fetchUserRequestWithId:
successBlock:^(id resultResponse,N错误*错误){
currentRequest+=1;
//步骤3:检查剩余请求。如果请求剩余,则调用“t_request()”。
if(currentRequest
注意:这仅在您使用不同的调用获取每个用户信息时才有帮助。如果在一次调用中获得所有用户信息,则只需使用NSSortDescriptor对用户进行排序
如果您在执行序列任务时遇到任何问题,可以在下面留下评论。因为Alarmofire正在异步方法中调用请求。这就是为什么所有的请求都是一次调用的,但是对于所有的请求,响应时间都不一样
若要按顺序调用所有请求,可以在前一个服务完成后调用服务
由于我们面临同样的问题,所以我们确实使用了调度块来执行序列任务
- (void)fetchAllUserAndStopWithCompletion:(void(^)(id resultResponse, BOOL isComplete))completion {
// Step 1: Define default parameters and limits.
__block NSInteger totalNumberOfUser = 4;
__block NSInteger currentRequest = 0;
__block dispatch_block_t t_request;
dispatch_block_t request = [^{
// Step 2: Fetch User information for currentRequest id.
[UserRequest fetchUserRequestWithId:<UserId or Any Unique Id>
successBlock:^(id resultResponse, NSError *error) {
currentRequest += 1;
// Step 3: Check for remaining request. If request is remaining then call ’t_request()’.
if (currentRequest < totalNumberOfUser) {
// Request Remaining
if (completion) {
id response = (!error)?resultResponse:nil;
completion(response, NO);
}
t_request();
}
else {
// All Request Completed
if (completion) {
id response = (!error)?resultResponse:nil;
completion(response, YES);
}
}
}];
} copy];
t_request = request;
request();
}
-(void)fetchAllUserAndStopWithCompletion:(void(^)(id resultResponse,BOOL isComplete))完成{
//步骤1:定义默认参数和限制。
__块NSInteger totalNumberOfUser=4;
__块NSInteger currentRequest=0;
__阻塞调度请求;
调度阻止请求=[^{
//步骤2:获取currentRequest id的用户信息。
[UserRequest fetchUserRequestWithId:
successBlock:^(id resultResponse,N错误*错误){
currentRequest+=1;
//步骤3:检查剩余请求。如果请求剩余,则调用“t_request()”。
if(currentRequest
注意:这仅在您使用不同的调用获取每个用户信息时才有帮助。如果在一次调用中获得所有用户信息,则只需使用NSSortDescriptor对用户进行排序
如果您在执行序列任务方面有任何问题,您可以在下面留下评论。您有4个用户,因此您调用了4次请求,并且在检索到所有4个用户后您想做些什么,这就是您的问题吗?很不清楚你想问什么really@Tj3n是的,没错,我想做点什么