1

我对 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 异步运行的事实有关,但我一直无法找到专门针对如何在构建命令行工具时解决此问题的解决方案。任何人都可以提供的任何方向将不胜感激。

干杯,

4

1 回答 1

1

NSOperationQueue 的参考说 for +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 进行了测试,但这应该可以工作。

dispatch_semaphore_wait此外,如果要在 URL 会话完成后进行同步,则需要调用。

于 2014-07-09T00:02:06.663 回答