AFNetworking同步调用(如/不同于) [英] AFNetworking synchronous calls (like/unlike)
问题描述
我需要实现的喜欢/不象在应用功能。所有API调用与 AFNetworking
制作和成功/错误处理程序( IOS块)。
I need to implement like/unlike functionality in app. All API calls are made with AFNetworking
and success/errors handlers (ios blocks).
问题是,在很短的时间周期当用户作出一个按钮的点击次数,一些请求是由服务器在一个错误的顺序接收,然后一切都变得错。例如像一倍或双不像发生。
Problem is that when user making many clicks on a button in a short period of time, some of the request are received by server in a wrong sequence and then everything becomes wrong. For example double like or double unlike happens.
有没有一种方法来发送通过所有要求 AFNetworking
同步?
Is there a way to send all request via AFNetworking
synchronously?
如果没有什么是最好的做法来设计这种API请求?
If no what is the best practice to design this kind of API requests?
推荐答案
如果你把他们在操作队列AFNetworking操作将完成事件之前返回。检查这个博客帖子: http://www.dribin.org /戴维/博客/存档/ 2009/05/05 / concurrent_operations /
AFNetworking operations will return before completion event if you put them in an operation queue. Check this blog post: http://www.dribin.org/dave/blog/archives/2009/05/05/concurrent_operations/
在你的情况,你需要创建一个类似于以下内容的子类的NSOperation:
In your case, you need to create an NSOperation subclass similar to the following:
//Header file
@interface LikeOperation : NSOperation
@property (readonly, nonatomic) BOOL isExecuting;
@property (readonly, nonatomic) BOOL isFinished;
+ (instancetype)operationWithCompletionSuccessBlock:(void(^)())onSuccess failure:(void(^)(NSError *anError))onError;
@end
//Implementation file
#import "LikeOperation.h"
typedef void (^SuccessBlock)();
typedef void (^ErrorBlock)(NSError*);
@interface LikeOperation()
@property (readwrite, copy, nonatomic) SuccessBlock onSuccess;
@property (readwrite, copy, nonatomic) ErrorBlock onError;
@property (assign, nonatomic) BOOL isExecuting;
@property (assign, nonatomic) BOOL isFinished;
@property (readwrite, strong, nonatomic) AFHTTPClient *client;
@end
@implementation LikeOperation
static NSString *const kBaseURLString = @"www.example.org";
static NSString *const kURLString = @"www.example.org/like";
- (id)initWithCompletionSuccessBlock:(void (^)())onSuccess failure:(void (^)(NSError *))onError
{
self = [super init];
if (self)
{
self.onSuccess = onSuccess;
self.onError = onError;
}
return self;
}
+ (instancetype)operationWithCompletionSuccessBlock:(void (^)())onSuccess failure:(void (^)(NSError *))onError
{
return [[self alloc] initWithCompletionSuccessBlock:onSuccess
failure:onError];
}
- (void)start
{
if (![NSThread isMainThread])
{
[self performSelectorOnMainThread:@selector(start)
withObject:nil
waitUntilDone:NO];
return;
}
NSString *key = NSStringFromSelector(@selector(isExecuting));
[self willChangeValueForKey:key];
self.isExecuting = YES;
[self didChangeValueForKey:key];
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSURL *baseURL = [NSURL URLWithString:kBaseURLString];
self.client = [AFHTTPClient clientWithBaseURL:baseURL];
});
NSURL *url = [NSURL URLWithString:kURLString];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
AFHTTPRequestOperation *operation = [self.client HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject) {
self.onSuccess();
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
self.onError(error);
}];
[operation start];
}
- (void)finish
{
NSString *isExecutingKey = NSStringFromSelector(@selector(isExecuting));
NSString *isFinishedKey = NSStringFromSelector(@selector(isFinished));
[self willChangeValueForKey:isExecutingKey];
[self willChangeValueForKey:isFinishedKey];
self.isExecuting = NO;
self.isFinished = YES;
[self didChangeValueForKey:isExecutingKey];
[self didChangeValueForKey:isFinishedKey];
}
@end
在这之后,你可以把上面的操作安全在NSOperationQueue和最大并发maxConcurrentOperationCount设置为1,这样的操作运行一个后另一个。您可能还需要探索的NSOperation的依赖,如<一个解释href=\"http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/NSOperation_class/Reference/Reference.html\" rel=\"nofollow\">http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/NSOperation_class/Reference/Reference.html
//Code to initialize the operation queue
self.queue = [[NSOperationQueue alloc] init];
self.queue.name = @"Post data queue";
self.queue.maxConcurrentOperationCount = 1;
//perform like
- (void)like
{
NSOperation *likeOperation = [LikeOperation operationWithCompletionSuccessBlock:^{
} failure:^(NSError *anError) {
}];
[self.queue addOperation:likeOperation];
}
这篇关于AFNetworking同步调用(如/不同于)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!