使用NSURLSessionDataTask和dispatch_source计时器进行定期服务器请求

时间:2014-12-02 01:55:56

标签: ios xcode grand-central-dispatch nsurlsession

需要一些帮助和解释,因为我真的陷入了我的问题。我需要这样做: 1)我向服务器发出一个请求,得到一些响应,然后我想每7秒发出一次请求(例子)。也得到一些回应。如果它满足几个条件 - >停止计时器并做一些事情。

主要问题是计时器永远不会停止,尽管事实上我总能得到正确的响应。我假设我错误地使用GCD。因为在调试中这段代码表现得很奇怪。

我做了什么:

这是我的请求功能(在我阅读了大约50个链接之后,它变成了这样的事情)

-(void)makeRequestWithURL:(NSString*)urlString andParams:(NSString*)params andCompletionHandler:(void(^)(NSDictionary *responseData, NSError *error))completionHnadler{

NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration];
NSURL *url = [NSURL URLWithString:urlString];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url
                                                       cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
request.HTTPMethod = @"POST";
request.HTTPBody = [params dataUsingEncoding:NSUTF8StringEncoding];

NSURLSessionDataTask *postDataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {

    if (completionHnadler) {
        if (error) {
            dispatch_async(dispatch_get_main_queue(), ^{
                completionHnadler(nil, error);
            });
        } else {
            NSError *parseError;
            json = [NSJSONSerialization JSONObjectWithData:data
                                                   options:NSJSONReadingMutableContainers
                                                     error:&parseError];
            dispatch_async(dispatch_get_main_queue(), ^{
                completionHnadler(json, parseError);
            });
        }
    }

}];

[postDataTask resume]; }

我像这样创建我的计时器:

dispatch_source_t CreateDispatchTimer(uint64_t interval,
                                  uint64_t leeway,
                                  dispatch_queue_t queue ,
                                  dispatch_block_t block) {
dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
if (timer) {

    // Use dispatch_time instead of dispatch_walltime if the interval is small
    dispatch_source_set_timer(timer, dispatch_walltime(NULL, 0), interval, leeway);
    dispatch_source_set_event_handler(timer, block);
    dispatch_resume(timer);
}
return timer; }

并称之为:

-(void)checkForPassenger {

timerSource = CreateDispatchTimer(7ull * NSEC_PER_SEC, 1ull * NSEC_PER_SEC, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

    if([self getNotificationsRequest] == YES) {
        dispatch_source_cancel(timerSource);
    } else {
        NSLog(@"go on timer");
    }
    NSLog(@"Driver checked for passenger!");

}); }

这是定期回复的代码:

-(BOOL)getNotificationsRequest {

NSString *urlString = @"http://primetime.by/temproad/do";
NSString *params = [NSString stringWithFormat:@"event={\"type\": \"in.getNotifications\"}&session_id=%@",session_id];


[self makeRequestWithURL:urlString andParams:params andCompletionHandler:^(NSDictionary *responseData, NSError *error) {
    if ([[responseData objectForKey:@"rc"] intValue] == 0) {


        NSArray *temp_notifications = [responseData objectForKey:@"notifications"];
        if (temp_notifications.count != 0) {
            notification = [[Notification alloc] initWithNotification:[[responseData objectForKey:@"notifications"] objectAtIndex:0]];
        }
    }
}];

if (notification) {
    return YES;
} else {
    return NO;
} }

这就是我在主要要求中所做的:

[self makeRequestWithURL:urlString andParams:params andCompletionHandler:^(NSDictionary *responseData, NSError *error) {

    if ([[responseData objectForKey:@"rc"] intValue] == 0) {
        route = [[Route alloc] initWithData:responseData];
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            [self checkForPassenger];
        });

    }
}];
NSLog(@"bye");

也许解释很糟糕所以我可以回答任何问题。 THX

0 个答案:

没有答案