当作为命令行工具运行时,如何让NSURLSession处理completionHandler

时间:2014-07-08 23:10:10

标签: objective-c nsurlsession command-line-tool completionhandler

我对Objective-C有点新鲜。我有一些PERL脚本从需要客户端证书身份验证的站点下载文件。我想将这些脚本从PERL移植到Objective-C命令行工具,然后我可以从终端运行。根据我的研究,我得出结论,NSURLSession应该适用于我需要做的事情。但是,我无法让NSURLSession在我的命令行工具中工作。它似乎构建良好没有错误,但不会从completionHandler返回任何内容。此外,我已将相同的代码放入Mac OS X App工具中,它似乎工作正常。

这是我的main.m文件:

#import <Foundation/Foundation.h>
#import "RBC_ConnectDelegate.h"

int main(int argc, const char * argv[])
{

    @autoreleasepool {

        // insert code here...

        NSURL *myURL =[NSURL URLWithString:@"http://google.com"];

        //[[[RBC_Connect alloc] init] connectGetURLSynch];
        RBC_ConnectDelegate *myConnect = [[RBC_ConnectDelegate alloc] init];
        [myConnect GetURL2: myURL];


    }
    return 0;
}

这是我的实施文件:

#import <Foundation/Foundation.h>


@interface RBC_ConnectDelegate : NSObject 

- (void)GetURL2:(NSURL *)myURL;

@property(nonatomic,assign) NSMutableData *receivedData;
//<==== note use assign, not retain
//do not release receivedData in a the dealloc method!

@end

这是我的实施文件:

#import "RBC_ConnectDelegate.h"

@implementation RBC_ConnectDelegate

- (void)GetURL2:(NSURL *)myURL2{
    //create semaphore
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
    // Create the request.
    NSLog(@"Creating Request");
    NSURLRequest *theRequest =
    [NSURLRequest requestWithURL:myURL2
                     cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
                 timeoutInterval:10.0];
     NSLog(@"Creating Session");
    NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration];
    NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration: defaultConfigObject delegate: nil delegateQueue: [NSOperationQueue mainQueue]];
     NSLog(@"Initializing Data Task");
    NSURLSessionDataTask * dataTask = [defaultSession dataTaskWithRequest:theRequest
                            completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {

                                NSLog(@"CompletionHandler");

                                if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
                                    NSInteger myStatusCode = [(NSHTTPURLResponse *) response statusCode];
                                    NSLog(@"Status Code: %ld", (long)myStatusCode);

                                }



                                if(error == nil)
                                {
                                    NSString * text = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
                                    NSLog(@"Data = %@",text);
                                }
                                else
                                {
                                NSLog(@"Error");
                                }
            dispatch_semaphore_signal(semaphore);
                                                        }];

    NSLog(@"Resuming Data Task");
    [dataTask resume];
}
@end

正如你所看到的,我试图在这里先做一些非常简单的工作,然后我就可以在此基础上进行构建。我所看到的一切表明,这可能与NSURLSession异步运行这一事实有关,但我无法找到一个解决方案,专门讨论如何在构建命令行工具时解决此问题。任何人都能提供的方向都将受到赞赏。

欢呼声,

1 个答案:

答案 0 :(得分:1)

NSOperationQueue的参考文献说,对于+mainQueue,主线程的运行循环控制操作的执行,因此您需要一个运行循环。将其添加到main

的末尾
while (1)
{
    SInt32 res = 0;
    @autoreleasepool
    {
        res = CFRunLoopRunInMode(kCFRunLoopDefaultMode, DBL_MAX, false);
    }

    if (kCFRunLoopRunStopped == res || kCFRunLoopRunFinished == res)
        break;
}

要致电-GetURL2:,请使用-[NSOperationQueue addOperation:]dispatch_async。您可以使用CFRunLoopStop停止执行。我用GCD而不是NSOperations进行了测试,但无论如何这都应该有效。

此外,如果您想在URL会话完成后进行同步,则需要致电dispatch_semaphore_wait

相关问题