gpt4 book ai didi

ios5 - iOS 5 NSURLConnection 与 NSOperationQueue - 提供 UI 反馈

转载 作者:行者123 更新时间:2023-12-04 05:54:38 26 4
gpt4 key购买 nike

我需要为 JSON Web 服务创建多个 NSURLConnections。我希望每个 WS 调用都保持 UI 通知,可能带有 UIActivityIndi​​catorView 和标签。到目前为止,我已经创建了一个 NSURLConnection 帮助类来处理连接并将 URL 委托(delegate)放置在 View 中。这对于使用单个 WS 调用更新 UI 非常有用。

对于多个调用,我正在尝试使用 NSOperationQueue。我想在队列中将MaxConcurrentOperationCount 设置为一个,以便每个操作一次执行一个。这是我的 View Controller 上的相关代码:

ViewController.m

#import "URLOperationHelper.h"

@implementation ViewController

- (IBAction)showPopup:(id)sender
{
// Dictonary holds POST values
NSMutableDictionary *reqDic = [NSMutableDictionary dictionary];

// Populate POST key/value pairs
[reqDic setObject:@"pw" forKey:@"Password"];
[reqDic setObject:@"ur" forKey:@"UserName"];

operationQueue = [[NSOperationQueue alloc] init];
[operationQueue setMaxConcurrentOperationCount:1];
[operationQueue cancelAllOperations];
[operationQueue setSuspended:YES];

URLOperationHelper *wsCall1 = [[URLOperationHelper alloc] initWithURL:@"urlString1" postParameters:reqDic urlDelegate:self];

URLOperationHelper *wsCall2 = [[URLOperationHelper alloc] initWithURL:@"urlString2" postParameters:reqDic urlDelegate:self];

[operationQueue addOperation:wsCall1];
[operationQueue addOperation:wsCall2];

}

// Did the URL Connection receive a response
-(void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
NSLog(@"Did receive response: %@", response);

NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;
int code = [httpResponse statusCode];

// Handle status code here

webData = [[NSMutableData alloc]init];
}

// Did the URL Connection receive data
-(void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
NSLog(@"Did receive data: %@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);

assert(webData != nil);
[webData appendData:data];
}

// Did the connection fail with an error?
-(void) connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog(@"%@", error);
}

// Executes after a successful connection and data download
-(void) connectionDidFinishLoading:(NSURLConnection *)connection
{
NSLog(@"Connection finished");
}

@end

这是我的 URLOperationHelper.m
  @implementation URLHelper  
- (id)initWithURL:(NSString *)urlPath
postParameters:(NSMutableDictionary *)postParameters
urlParentDelegate:(id) pDelegate
{
if(self = [super init])
{
connectionURL = urlPath;
postParams = postParameters;
parentDelegate = pDelegate;
}

return self;
}

- (void)done
{
// Cancel the connection if present
if(urlConnection)
{
[urlConnection cancel];
urlConnection = nil;
}

// Alert
[self willChangeValueForKey:@"isExecuting"];
[self willChangeValueForKey:@"isFinished"];

executing = NO;
finished = YES;

[self willChangeValueForKey:@"isFinished"];
[self willChangeValueForKey:@"isExecuting"];
}

- (void)cancel
{
// Possibly add an NSError Property
[self done];
}

- (void)start
{
// Make sure this operation starts on the main thread
if(![NSThread isMainThread])
{
[self performSelectorOnMainThread:@selector(start) withObject:nil waitUntilDone:NO];
return;
}

// Make sure that the operation executes
if(finished || [self isCancelled])
{
[self done];
return;
}

[self willChangeValueForKey:@"isExecuting"];
executing = YES;

[self main];
[self willChangeValueForKey:@"isExecuting"];
}

- (void)main
{
NSError *error = nil;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:postParams options:NSJSONWritingPrettyPrinted error:&error];

// Convert dictionary to JSON
NSString *requestJSON = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];

NSLog(@"JSONRequest: %@", requestJSON);

// Declare Webservice URL, request, and return data
url = [[NSURL alloc] initWithString:connectionURL];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
NSData *requestData = [NSData dataWithBytes:[requestJSON UTF8String] length:[requestJSON length]];

// Build the request
[request setHTTPMethod:@"POST"];
[request setValue:[NSString stringWithFormat:@"%d", [requestData length]] forHTTPHeaderField:@"Content-Length"];
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[request setHTTPBody:requestData];

// Connect to Webservice
// Responses are handled in the delegates below
urlConnection = [[NSURLConnection alloc] initWithRequest:request delegate:parentDelegate startImmediately:YES];
}

- (BOOL)isConcurrent
{
return YES;
}

- (BOOL)isExecuting
{
return executing;
}

-(BOOL)isFinished
{
return finished;
}

@end

我遇到的问题是 URLOperation 的 Start 方法永远不会被调用。 OperationQueue 被创建并被调用,但之后没有任何事情发生,无论是执行还是线程方面。

另外,像这样使用 NSOperationQueues 提供 UI 反馈是正确的思路吗? IE。从操作中调用 NSURLDelegates?

最佳答案

如果设置 setSuspendedYES在添加操作之前,您的操作将排入暂停队列。我建议不要暂停队列

此外,您的操作永远不会结束。您需要将操作本身分配为委托(delegate)并实现所有必要的委托(delegate)方法。在这些方法中,您可以将消息转发到您的parentDelegate。并决定何时完成并在适当的时候调用你的 done 方法(我建议 connection:didFailWithError:connectionDidFinishLoading: )

这里有一个很好的教程:http://blog.9mmedia.com/?p=549

您也没有完全正确地实现键值编码编译属性。无论何时调用 willChangeValueForKey:您还需要调用didChangeValueForKey然后:

- (void)start
{
...
[self willChangeValueForKey:@"isExecuting"];
executing = YES;
[self didChangeValueForKey:@"isExecuting"];

[self main];
}

和:
- (void)done
{
...

// Alert
[self willChangeValueForKey:@"isExecuting"];
[self willChangeValueForKey:@"isFinished"];

executing = NO;
finished = YES;

[self didChangeValueForKey:@"isFinished"];
[self didChangeValueForKey:@"isExecuting"];
}

有关 KVC,请参阅此 Q/A: when to use "willChangeValueForKey" and "didChangeValueForKey"?

关于ios5 - iOS 5 NSURLConnection 与 NSOperationQueue - 提供 UI 反馈,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9657228/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com