gpt4 book ai didi

objective-c - iOS RESTful POST调用在UIWebView中有效,但从线程调用时无效

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:21:57 27 4
gpt4 key购买 nike

我正在尝试在iOS应用中创建一个身份验证系统,该系统允许用户登录和注册(如果他们还没有帐户)。我昨天完成了登录系统的运行,但是当我为注册系统设置了代码时,该代码甚至无法ping通服务器。然后,我尝试再次测试登录系统,该代码现在也无法ping通服务器。

RegistrationTableViewController的相关代码(这是一个自定义TVC,在某些单元格中包含文本字段-例如,请考虑使用该视图来创建新的日历事件):

- (IBAction)signUpButtonPressed { 
// Get the values out of the text fields that the user has filled out.
NSString *email = self.emailTextField.text;
NSString *firstName = self.firstNameTextField.text;
NSString *lastName = self.lastNameTextField.text;
NSString *password = self.passwordTextField.text;
// Assuming that sign-up could potentially take a noticeable amount of time, run the
// process on a separate thread to avoid locking the UI.
dispatch_queue_t signUpQueue = dispatch_queue_create("sign-up authenticator", NULL);
dispatch_async(signUpQueue, ^{
// self.brain refers to a SignUpBrain property. See the code for the class below.
[self.brain signUpUsingEmail:email firstName:firstName lastName:lastName
andPassword:password];
dispatch_async(dispatch_get_main_queue(), ^{
[self performSegueWithIdentifier:@"ShowMainFromSignUp" sender:self];
});
});
dispatch_release(signUpQueue);
}

SignUpBrain的相关代码:
- (void)signUpUsingEmail:(NSString *)email firstName:(NSString *)firstName
lastName:(NSString *)lastName andPassword:(NSString *)password {
self.email = email;
self.firstName = firstName;
self.lastName = lastName;
self.password = password;

// Handle sign-up web calls.
NSMutableURLRequest *signUpRequest = [[NSMutableURLRequest alloc] initWithURL:[NSURL
URLWithString:@"URL GOES HERE"]]; // obviously there's an actual URL in real code
NSString *postString = [NSString stringWithFormat:@"uname=%@&pw=%@&fname=%@&lname=%@",
email, password, firstName, lastName];
//NSLog(postString);
[signUpRequest setHTTPMethod:@"POST"];
[signUpRequest setHTTPBody:[postString dataUsingEncoding:NSUTF8StringEncoding]];
NSURLConnection *signUpConnection =
[NSURLConnection connectionWithRequest:signUpRequest delegate:self];
[signUpConnection start];

// Store any user data.
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
self.signUpResponse = data;
NSError *error;
NSDictionary *jsonLoginResults = [NSJSONSerialization JSONObjectWithData:data
options:0 error:&error];
if (error) {
NSLog(error.description);
}
NSLog(jsonLoginResults.description);

// Return whether the user has successfully been registered.
// If success is 1, then registration has been completed successfully. 0 if not.
if ([jsonLoginResults objectForKey:@"status"]) {
NSLog(@"Success!");
}
}

我还将注意到,我创建了一个在UIWebView中使用这些相同的Web调用的测试,并且该测试成功进行。

如果需要澄清任何内容或包含更多代码,请告诉我!提前致谢。

最佳答案

通常情况下,您无需在其他线程上运行网络操作。

您需要避免的是在主线程上进行同步操作。这将导致iOS终止您的应用程序,因为它会在网络传输繁忙时停止响应事件。

苹果的建议是在主线程上使用异步操作,而不是在另一个线程上使用同步操作。

使用异步操作将导致网络本身在后台运行。您可以将其视为Apple的专用线程。当iOS认为合适时,将在主线程上以正确的顺序调用您的委托方法,以赶上网络。

使用NSURLConnection

Apple在《 URL加载系统编程指南》 Using NSURLConnection中提供了有关如何使用NSURLConnection的示例。这是一篇简短的文章,其中包含许多简单的代码示例。您应该花几分钟来阅读此内容。

简而言之,这是模式:

  • 为您的响应数据保留一个NSMutableData
  • 清除NSMutableData中的内容didReceiveResponse实例。 (在重定向时,您可能会收到多个didReceiveResponse事件,但您只能使用最后一个的数据。)
  • 将您从didReceiveData接收的数据追加到NSMutableData。不要试图立即处理它;您通常会在一次转移中收到多个didReceiveData事件。
  • connectionDidFinishLoading中,您的数据已完成。在这里,您可以使用它来做一些事情。

  • 当拥有所有数据时,可以将其发送到其他线程,也可以将(更简单的) dispatch_async发送到不在主线程上运行的队列。请参见 URL Loading System Programming Guide的清单5,“示例connectionDidFinishLoading:实现”。

    这里的想法是,您开始(或重新启动)累积 didReceiveResponse:中的数据,将数据追加到 didReceiveData:中,并实际上对 connectionDidFinishLoading:中的数据进行某些操作。

    当然,它 可以在另一个线程上运行 NSURLConnection。该线程将需要使用运行循环来接收来自网络的委托事件。但是除非出于某种原因您 需要一个单独的线程,否则使用异步网络是Apple的解决方案。

    使用 NSURLConnection要求类成员在传输数据时累积数据。这意味着,如果您要同时进行多个传输,则需要更复杂的东西。可能是包装器类,用于驱动 NSURLConnection,并使每个响应分开。在编写此包装器类时,您可能已经编写了朴素的 AFHTTPRequestOperation版本,它是AFNetworking的一部分。

    假设您一次只进行一次传输,则代码看起来像这样:
    - (void)signUpUsingEmail:(NSString *)email firstName:(NSString *)firstName
    lastName:(NSString *)lastName andPassword:(NSString *)password {

    // set up your connection here, but don't start it yet.

    receivedData = [[NSMutableData alloc] init]; // receivedData should be a class member
    [signUpConnection start];
    }

    - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
    [receivedData setLength:0];
    }

    - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    [receivedData appendData:data];
    }

    - (void)connection:(NSURLConnection *)connection
    didFailWithError:(NSError *)error {
    // do something with error here
    // if you're not using ARC, release connection & receivedData here
    }

    - (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    dispatch_async(someQueue, ^{
    // do something that takes a long time with receivedData here
    dispatch_async( dispatch_get_main_queue(), ^{
    // go back to your main screen here
    });
    });
    // if you're not using ARC, release connection & receivedData here
    }

    使用AFNetworking

    现在,我已经解释了所有这些,我将建议一个替代方法。使用 AFNetworking可能会更好。

    AFNetworking是一个开源的第三方库。它最基本的类将 NSURLConnection包装在 NSOperation中(因此,可以将其添加到 NSOperationQueue中)。 AFNetworking会自动处理这些事件。而是编写一个完成块。当您获得此块时,传输要么成功要么失败。如果失败,则该错误在 AFHTTPRequestOperation实例上可用。如果成功,则可以使用 AFHTTPRequestOperation实例上的数据。

    (注意:我相信 AFHTTPRequestOperation实际上确实从另一个线程运行了连接。但是,它是编写良好且经过测试的代码。这样做没有“错误”,它很难实现,而且通常是不必要的。但是如果您的库对您有用,为什么不呢?)

    AFNetworking提供了 NSURLConnection没有的一些HTTP逻辑。使用AFNetworking,您只需使用 AFHTTPRequestOperation并设置完成块。以上所有内容都类似于:
    HTTPOperation = [[AFHTTPRequestOperation alloc] initWithRequest: URLRequest];
    HTTPOperation.completionBlock = ^{
    dispatch_async(someQueue, ^{
    // get possible error or content from HTTPOperation
    }
    };
    [HTTPOperation start];

    过去,我直接使用NSURLConnection编写。但是最近,我一直在更频繁地使用AFNetworking。与其他一些库不同,它的形状与NSURLConnection并没有根本不同。实际上,它使用NSURLConnection,它包装在NSOperation中(希望Apple现在可以发布到任何版本)。至少值得考虑。

    关于objective-c - iOS RESTful POST调用在UIWebView中有效,但从线程调用时无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10745510/

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