简体   繁体   English

使用阻塞或类似方法从NSURLConnection获取数据

[英]Getting data from NSURLConnection using blocking or similar

Hi guys this will be my first post and am pretty new to Objective-C though not entirely new to coding. 嗨,大家好,这是我的第一篇文章,虽然不是完全陌生的编码,但对Objective-C还是很新的。 I've been doing a lot of reading and a lot of Googling and a lot of my answers have come from this site. 我一直在阅读大量书籍,并且在Google上进行了很多搜索,并且我的很多答案都来自该网站。 So now I'm really stuck I figured it was about time I asked the experts. 所以现在我真的很困惑,我想是时候该问专家了。

I'm basically trying to get the raw HTML data from a given URL so that I can parse it for information. 我基本上是试图从给定的URL中获取原始HTML数据,以便我可以解析它以获取信息。 I have all the parsing sorted, and can retrieve the raw HTML however I'm struggling to understand how to get the program to stop while the data arrives from NSURLConnection so I can use it. 我已经对所有解析进行了排序,并且可以检索原始HTML,但是我正努力了解如何在数据从NSURLConnection到达时如何停止程序,以便可以使用它。 Currently my program whizzes past the connection and the holding String gets left as empty, until shortly after when its filled by the request. 目前,我的程序开始经过连接,并且保留的String保留为空,直到被请求填充后不久。 I believe I need to use a "Syncronous" connection but this is frowned upon because it freezes the UI while its processing the request. 我相信我需要使用“同步”连接,但是对此并不满意,因为它在处理请求时冻结了UI。 I'm trying to call it like this .... 我正试图这样称呼它....

urlData = [getURLClass getURL: @"http://www.google.co.uk"];

Hoping to get raw HTML in to the String urlData so I can parse it.My current code from my class is below.... 希望将原始HTML输入到String urlData以便我可以对其进行解析。

//Create the request
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:urlString]];

//Open NSURLConnection with 'request'
[NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
    //If we receive something
    if (data) {
        //Pass and decode to string
        receivedData = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
        NSLog(@"Received HTML: %@", receivedData); 
    }

    //Something went wrong
    else {
       // ToDO: Sort out any errors

    }
}];

return receivedData;

When this is run the log shows "Received HTML: nil" and the return value is also blank, but if I wait a moment then call the class again its been filled with data from the previous request. 运行此命令时,日志显示“ Received HTML:nil”,返回值也为空,但是如果我稍等片刻,则再次调用该类,该类已充满了先前请求中的数据。 I did try another method which the data was retrieved in to 我确实尝试了另一种将数据检索到的方法

-(void) connectionDidFinishLoading

But this leaves me the problem that I cannot "return" the data from the Method that was called. 但这给我留下了一个问题,即我无法从调用的方法中“返回”数据。 As I said I'm very new to Objective-C. 正如我所说的,我对Objective-C还是很陌生。 I'm aware there are discontinued wrappers like ASIHTTPRequest , but I'm sure there is a simpler answer to this than using someone else's class. 我知道有不连续的包装器,例如ASIHTTPRequest ,但是我敢肯定,比使用其他人的类更简单的答案。 It will also help me to learn if I can find an answer, I simply need to get the program to wait while the data is received before the class return it. 这也将帮助我学习是否可以找到答案,我只需要让程序在类收到数据之前等待接收数据。 I may be trying to run before I can walk with Obj-C, but my program is useless unless I can interact with the web. 在使用Obj-C之前,我可能正在尝试运行,但是除非可以与Web交互,否则我的程序是无用的。

Thanks in advance. 提前致谢。 Plasma 等离子体

You should be able to do what you want with the NSString function initWithContentsOfURL : 您应该可以使用NSString函数initWithContentsOfURL进行所需的操作

NSError* error;
NSString* htmlData = [[NSString alloc] initWithContentsOfURL:myURL encoding:NSUTF8StringEncoding error:&error];

It might also be NSASCIIStringEncoding for the encoding ... but in any case it gives you the string synchronously. 编码也可能是NSASCIIStringEncoding ...,但是无论如何它都会为您同步提供字符串。

EDIT: 编辑:

Corrected Spelling initWithContent* s *OfURL, added alloc 纠正了拼写initWithContent * s * OfURL,添加了alloc

I wrote a class file for this type of situation. 我为这种情况编写了一个类文件。

CAURLDownload.h: CAURLDownload.h:
http://localhostr.com/file/vGtIIpO/CAURLDownload.h http://localhostr.com/file/vGtIIpO/CAURLDownload.h

CAURLDownload.m: CAURLDownload.m:
http://localhostr.com/file/TAieiAE/CAURLDownload.m http://localhostr.com/file/TAieiAE/CAURLDownload.m

Basically, you want to call 基本上,你想打电话
[CAURLDownload downloadURL:URL target:self selector:@selector(finishedSelector: connection:) failSelector:@selector(failureSelector:) userInfo:userInfo];

URL is an NSURL and userInfo is an NSDictionary. URL是一个NSURL,而userInfo是一个NSDictionary。

Basically, you call that method with the appropriate parameters and execute your parsing in finishedSelector. 基本上,您可以使用适当的参数调用该方法,然后在finishSelector中执行解析。 Example: 例:

[CAURLDownload downloadURL:[NSURL URLWithString:@"http://couleeapps.hostei.com"]
                    target:self
                  selector:@selector(downloadFinished:connection:)
              failSelector:@selector(downloadFailed:)
                  userInfo:nil];

And for the methods: 对于方法:

- (void)downloadFinished:(NSData *)recievedData conneciton:(CAURLDownload *)connection {
    //Parse recievedData
    NSString *recievedString = [[[NSString alloc] initWithData:recievedData] autorelease];
    //Etc.
}

- (void)downloadFailed:(CAURLDownload *)connection {
    NSLog(@"Download Failed!");
    //Do something
}

This has both the upsides of not locking the UI, being memory-friendly, and callable without a pointer required (singleton). 这具有不锁定UI,对内存友好以及无需指针即可调用(单例)的优点。

Unfortunately the SDK as supplied by Apple doesn't have any convenience functions to make this super simple. 不幸的是,Apple提供的SDK没有任何便利功能可以使此超级简单。 You have to do it all yourself using NSURLConnection. 您必须使用NSURLConnection自己做。 What I do is make a wrapper class that executes the NSURLConnection and then when the data is completely received it calls a completion block that you provide. 我要做的是创建一个执行NSURLConnection的包装器类,然后在完全接收到数据时调用您提供的完成块。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM