AFNetworking同步调用(如/不同于) [英] AFNetworking synchronous calls (like/unlike)

查看:191
本文介绍了AFNetworking同步调用(如/不同于)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要实现的喜欢/不象在应用功能。所有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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆