NSData / Retrieving content from a page - iphone

I have a page that displays one string on a blank page. I need to retrieve that string. How would I do it if I wanted to do it both, synchronously and asynchronously? (I would appreciate if someone gave me the method names for both synch and asynch).
Thank you,

You can use NSString's stringWithContentsOfURL:encoding:error: method to get the HTML page synchronously and later parse it using NSXMLParser.
Since stringWithContentsOfURL:encoding:error: is a blocking call, you should put it in a method and invoke the method using performSelectorInBackground:withObject:. This will retrieve the HTML page in the background.
Once you have the string, create an instance of NSXMLParser and get the string. This one is asynchronous process.
Few examples on how to use NSXMLParser - Make NSXMLParser your friend and BNR - Parsing XML in Cocoa.

Have a look at the NSURLConnection reference. The methods you want are there. Also, read the URL Loading guide, it has some code examples for both synchronous and asynchronous loading.
The body data of the repsonse will be the string you want. You'll need to be a bit careful about which encoding was used by the web site. If not specified in the response at all, it will be ISO-8859-1, otherwise it will probably be specified in the Content-Type header of the response. You then need to convert the data to an NSString with initWithData:encoding:
NB if you are not on the main thread, you can use NSStering's stringWithContentsOfURL:usedEncoding:error:. You shouldn't use this on the main thread because it is a synchronous method.

Related

HTTP post with UIWebview?

I am quite new to Objective-C coding, learning at College at the moment so. Anyways, how do I perform a HTTP post with a UIWebview so that I can update the view when needed for a different flyer to put put there etc.
I may not even need to use HTTP post doing this, but my co-partner who is coding for Android insists I may need to!
Any help?
I'm not sure what you mean by flyer. But if you want a web page to appear in a UIWebView you don't need to use HTTP post, you just pass the url of a page to load to the UIWebView, or if you already have html content etc. you can load that content directly.
You can make HTTP requests directly but you probably don't need to. What exactly is it you want to display in the UIWebView?
To make an HTTP Connection start by learning about NSURLConnection at iOS Developer Library
The first thing you're going to want to start with is making your NSURL objects then make your NSURLRequest with the parameters as well as the URL of your request. Then make a NSURLConnection and initiate the connection either asynchronously (preferred) or synchronously. If you want a synchronous (blocking) connection initialize it like so
NSError *error;
NSURLResponse *responseHandler;
NSData *response = [myNSURLConnection sendSynchronousRequest:myNSURLRequest, returningResponse:&responseHandler,error:&error];

iPhone: Asynchronous HEAD method

I am very new here. I am trying to update the content of a file from a webserver only if it has changed. I found an example of code here using a synchronous connection in NSURLconnection.
Is it possible to do asynchronously?
NSURLConnection has the method sendSynchronousRequest:returningResponse:error: for synchronous connection. It also has a method sendAsynchronousRequest:queue:completionHandler: for async connection. You need to create a block for completionHandler parameter, which handles the response from web server.
Also:
initWithRequest:delegate:
initWithRequest:delegate:startImmediately:
start
are available for async use. You gonna need to implement some methods of NSURLConnectionDelegate to handle the async response.
Please refer to NSURLConnection Class Reference and NSURLConnectionDelegate Protocol Reference.
i think ASIHTTPRequest is the easiest solution:
set the request Method for your ASIHTTPRequest
// HTTP method to use (eg: GET / POST / PUT / DELETE / HEAD etc). Defaults to GET
NSString *requestMethod;
or you can use a download cache
ASIHTTPRequest can automatically store downloaded data in a cache for use later. This can be helpful in many situations...

iOS - Is it possible that [NSData dataWithContentsOfURL:url] would return only part of the bytes of the content?

Will [NSData dataWithContentsOfURL:url] either return the full amount of bytes on success, or nil if something goes wrong?
Is there a chance, that it would return maybe only half of the bytes of the content... perhaps if their internet connection fails halfway through?
If there is a chance that it would return only partial data, is there some other function I could use that would be more reliable and I would be able to know definitely whether they got the full amount of data or not?
I'm not sure about the implementation of -dataWithContentsOfURL: but using a sychronous method like this is not really recommended anyway.
Something based on NSURLConnection is your best bet, but you need to be aware of a few things. Most people don't realize that if the server disconnects while an NSURLConnection is receiving data, it will not cause the download to fail with an error. The -connectionDidFinishLoading: delegate method will be called as normal. Many people get this wrong.
If you want to be sure you have all the data, you need to handle the -connection:didReceiveResponse: delegate method and save the value of [response expectedContentLength]. Then in -connectionDidFinishLoading: you can make sure you received the same number of bytes as expected, and generate an error if not.
There are many free libraries out there based on NSURLConnection like AFNetworking. However you need to beware of bad code. I've just checked the source to AFNetworking and it appears they also do not check for the case where the server sends back less data than the Content-Length header specifies. Also note that the popular ASIHTTPRequest is no longer being actively developed and has received some criticism over its implementation.
I'll leave it up to others to suggest other alternative libraries, but NSURLConnection is the right direction.
If you 'worry' about such a thing I'd recommend using NSURLConnection with it's appropriate delegates.
The async approach (that is NSURLConnection) is imho always better.

Streaming JSON with AFNetworking on IOS

What would be the most elegant way to receive data from a streaming JSON API using AFNetworking? AFNetworking provides excellent support for receiving non-streaming data from JSON APIs, but I couldn't find any examples of streaming JSON.
AFNetworking does not have a built-in streaming SAX-style JSON operation, but it should be straight forward to create your own.
Create a subclass of AFJSONRequestOperation
Use the outputStream property of the operation during initialization to hook it up to a JSON parser that supports SAX-style parsing (such as Yajl). The parser will read data and build up the JSON object as it comes in
Hook up the responseJSON property to read the cached object from the parser
...or depending on how you're doing streaming, you may need to add a new property that defines a block to execute when new JSON objects come back (e.g. setReceivedJSONBlock:((^)(void (id JSON))block). This block will probably be triggered by delegate methods sent from the parser (e.g. <YAJLParserDelegate> -parserDidEndDictionary:).
If you are able to get this working, I would encourage you to publish and share this with others. I think this could be useful to quite a few people.

Accessing XML data online?

I am just testing an app to get data off our web server, previously I had been using:
NSURL, NSURLRequest, NSURLConnection etc. to get the data that I wanted.
But I have just noticed that if I swap to using XML I can simply do the following and pass the results to NSXMLParser:
NSURL *url = [NSURL URLWithString:#"https://www.fuzzygoat.com/turbine?nbytes=1&fmt=xml"];
Am I right in thinking that if your just after XML this is an acceptable method? It just seems strongly short compared to what I was doing before?
gary
That code only creates a URL object that represents a URL. It doesn't make any request or download any data. You still need to use NSURLRequest and NSURLConnection in order to actually download any data from the server.
Also, stay away from methods like 'initWithContentsOfURL:` and friends, unless you understand that they will block the thread that they are called on until complete. For network services, this method shouldn't be used because it'll block your UI for an indeterminate time, because you can't predict how fast the internet connection will be wherever the app is used.
NSURLConnection's asynchronous request system is exactly what you need. It won't block the UI, and provides a nice encapsulated interface to downloading data from a remote location.
This is definitely the right way to go. There do exist many different connection methods (including my favorite, ASIHTTPRequest) and many, many different xml parsers (including my favorite, KissXML) that are faster or more memory efficient than the Apple built in methods.
But to answer your question, yes, your logic and design pattern is correct.
UPDATE: Because Jasarien seems to think the question talks about asynchronous actions, I will discuss that here. ASIHTTPRequest handles async very very easily. Just check out the quick samples.
Depending on how much XML you get back from the web service, NSXMLParser may not be ideal because the entire XML document has to be read into memory.
Memory is pretty scarce on an iPhone, so using a SAX parser like that in libxml2 is probably better for larger XML files. Instead of reading the entire document into memory, the XML is streamed through and parsed for specific nodes of interest. The memory overhead is lower because less data is stored at once.
Once a node of interest is parsed, an event handler is called to do something useful, like store the node data somewhere.
In this case, take a look at Apple's XMLPerformance sample project for example code.