I'm currently parsing an XML file that resides in my bundle using NSXMLParser with the following line:
NSURL *xmlURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"XMLFileName" ofType:#"xml"]];
But I want to put the same file on my server instead. I can't find an example of how to call the same file from my server. Any help is appreciated.
lq
NSURL has several methods for creating URLs, one of which is -URLWithString:; like so:
NSURL *xmlURL = [NSURL URLWithString:#"http://example.com/example.xml"];
That URL can be passed directly to NSXMLParser; but you might want to do so in a secondary thread.
If you want to HTTP GET the file from your server then you should look at NSURLConnection. It allows you to do synchronous or asynchronous HTTP requests.
Related
I want to detect if the URL is valid. So I see the following function.
+ (id)URLWithString:(NSString *)URLString
As the Apple Documentation said, an NSURL object initialized with URLString. If the string was malformed, returns nil. But actually, I call URLWithString with any string, it will return not nil. This documentation is wrong?
And could you provide a workaround to detect if URL is valid?
The documentation isn't wrong - NSURL supports both absolute and relative URLs. Additionally, it's not just used to remote (web) URLs, but for local file URLs as well. For example:
// Totally valid NSURL
NSURL *url = [NSURL URLWithString:#"http://google.com"];
// Just as valid NSURL
NSURL *url2 = [NSURL URLWithString:#"2rwehrfuiw34twef"];
You don't get any guarantees that the URL is reachable. It does guarantee you URL complies with RFC 2396. If you want to check that a URL is available you can either use the checkResourceIsReachableAndReturnError: method (which is available from iOS 5 onwards, but should only be used for file path URLs) or make a network request for it (which you'll have to do if your URL isn't a file path).
I would like to take an NSURLRequest and turn it into some usable data that is ready to be written to a socket() instead of something like an NSURLConnection.
What is the best way to accomplish this?
NO!
You can create a NSMutableURLRequest and provide that request with a HTTPBodyStream then create a NSURLConnection to send the request.
The HTTPBodyStream is an NSInputStream the request will read the body from. You can get it value from user, file or NSData.
I am using objective C and I am trying to load a website without opening it in Safari :
I am using the following function :
NSString *website =[NSString stringWithFormat:#"http://www.website.com"];
NSString *connected = [NSString stringWithContentsOfURL:[NSURL URLWithString:website ]encoding:NSStringEncodingConversionAllowLossy error:nil];
but when I check in my database I noticed that it does not load the website , when I load it in the browser it does detect it tho , any reasons ?
thanks
You probably want to use the NSURLConnection class to retrieve data from the network. It will provide a much more useful set of errors, etc.
For simple (but blocking), you can start off with -sendSynchronousRequest:returningResponse:error:, which retrieves a URL from the network giving you the data (in the return value), the HTTP Response, and an error.
NSURL *url = [NSURL URLWithString: #"http://www.website.com"];
NSURLRequest *request = [NSURLRequest requestWithURL: url];
NSURLResponse *response;
NSError *error;
NSData *data = [NSURLConnection sendSynchronousRequest: request returningResponse: &response error: &error];
If data isn't nil, you've gotten a valid response, otherwise error contains information about the response. You still need to double-check the response in order to make sure you got what you wanted (not a "successful" response that resulted in an error due to the server sending back an error code for HTTP).
In the future, if you need to do a POST command, you can use NSMutableURLRequest and set the type of the request.
Vlad is right, but your code will also only load one file. When you open that file in a browser like Safari, the browser will recursively load all referenced files and will handle any redirect that is present.
UPDATE
In a browser, using the URL without the file name works. I'm not sure you can do that with stringWithContentsOfURL: or with an NSURLConnection.
If the file name is something like "index.html" or whatever it is, try adding that to your URL. These methods load files, so I am betting that you need to provide a fully defined URL, including the file name.
Is it possible to use an NSURLConnection/NSURLRequest combination to send a PUT request to a server with a Content-Range header? By that I mean I want to resume an upload to the server which can accept a byte range in the request to resume the upload.
I see you can set an NSInputStream as the request body so I figured that I could subclass that and override the the open/seek functions and set the request header but it seems to call on undocumented selectors and break the implementation.
I'm sure I could do this with CFNetwork but it just seems like there must be a way to do it with the higher level APIs.
Any ideas on where to start?
EDIT:
To answer my own question, this is indeed possible after reading a blog [http://bjhomer.blogspot.com/2011/04/subclassing-nsinputstream.html] which details the undocumented callbacks which relate to CFStream. Once those are implemented I can call the following in the open callback to skip ahead:
CFReadStreamSetProperty((CFReadStreamRef)parentStream, kCFStreamPropertyFileCurrentOffset, (CFNumberRef)[NSNumber numberWithUnsignedLongLong:streamOffset]);
Thanks,
J
I think the server needs to supports put method combines with range but this will be the way to do it with high level Objective-C API
NSURL *URL = [NSURL URLWithString:strURL];
NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:URL];
NSString *range = [NSString stringWithFormat:#"bytes=%lld-%lld",bytesUploaded,uploadSize];
[urlRequest addValue:range forHTTPHeaderField:#"Range"];
[urlRequest setHTTPMethod:#"PUT"];
self.connection = [NSURLConnection connectionWithRequest:urlRequest delegate:self];
Cheers
First, if you want to do fancy work with HTTP, I typically recommend ASIHTTPRequest. It's solid stuff that simplifies a lot of more complicated HTTP problems. It's not really needed for setting a simple header, but if you're starting to build something more complex, it can be nice to move over to ASI sooner rather than later.
With an NSMutableURLRequest, you can set any header you want using addValue:forHTTPHeaderField:. You can use that to set your Content-Range.
Like I posted in my comment, you can facilitate what you want without dropping down to the CoreFoundation level:
As NSInputStream inherits NSStream, it is possible to prepare the stream as follows:
NSNumber *streamOffset = [NSNumber numberWithUnsignedInteger:lastOffset];
[inputStream setProperty:streamOffset forKey: NSStreamFileCurrentOffsetKey];
(Assuming lastOffset is an NSUInteger representation of your last file offset in bytes and inputStream is the stream you want to set as the request's HTTPBodyStream.)
What's the easiest way to retrieve text and upload text to a server? And how would I create files from the app on the server?
the easiest way to read text from an http endpoint on a web server is:
NSURL *url = [NSURL URLWithString:#"http://www.apple.com"];
NSString *content = [NSString stringWithContentsOfURL:url encoding:NSASCIIStringEncoding];
to save text, i would use a simple rest based xml web service where i would post the text data to this service and read the appropriate response back to know if the operation was successful