I have a method for downloading a file as file_name.zip to the documents directory. However, if I receive an error, such as 'file does not exist', the library is writing the JSON payload to file_name.zip.
How do we check for JSON error in requestFinished:?
responseString or responseData is always null.
You probably want to check the request.responseStatusCode and check against a 404 error. But honestly you should look into AFNetworking. ASIHTTPRequest is no longer supported and AFNetworking has success/failure blocks.
Related
I use Alamofire 4.5.1 to download some mp3 files.
If I provide incorrect URL or the request can't be authorised I get an error with 4xx status code (as it is supposed to be) and in my particular case xml with the error explanation.
The issue is that Alamofire saves the error xml response to my destination url, which looks like: .../my-sound-file.mp3
In other place in my app, which is decoupled from downloading code, I might later check if I have .../my-sound-file.mp3 on disk and try to play it, which obviously fails since my sound file is actually xml file with mp3 extension.
Is there a nicer way to prevent Alamofire saving an error data as an originally requested file?
The code I use (with my crude solution to this issue):
let destination: DownloadRequest.DownloadFileDestination = ...
let request = self.sessionManager.download(url, to: destination)
request.validate()
request.response { response in
if response.error == nil {
// do some stuff
} else {
// So far I am forced to manually remove file in case of error
try? FileManager.default.removeItem(at: destURL)
// propagate error
}
}
I stumbled upon this because I assumed that if a request validation fails the destination URL should be empty.
I think I am not the only one with this assumption: Alamofire: file download and validation failure
Personally, I delete the file in case of error. Just as you propose.
I am using PromiseKit and I want to retrieve a JSON file.
[NSURLConnection GET:#"http://127.0.0.1/pack01.json"].then(^(NSDictionary *json) {
NSArray *questions = json[#"questions"];
Everything is fine on localhost but when I try it from another source (same file) it gives me an error:
[NSURLConnection GET:#"https://dl.dropboxusercontent.com/u/11377305/resources/pack01.json"].then(^(NSDictionary *json) {
NSArray *questions = json[#"questions"];
Error
[__NSCFData objectForKeyedSubscript:]: unrecognized selector sent to instance 0xb07c880
JSON file:
https://dl.dropboxusercontent.com/u/11377305/resources/pack01.json
Why is it working on localhost?
I would appreciate any suggestions or even any thoughts on what questions I should be asking.
The error indicates that you're being passed an NSData rather than an NSDictionary from the remote URL.
The PromiseKit documentation states:
PromiseKit reads the response headers and decodes the result you actually wanted (in a background thread):
Therefore it's a safe bet that your remote server (which is DropBox in this case) isn't indicating that the returned data is formatted as JSON. So PromiseKit isn't parsing it.
EDIT: confirmed. DropBox is returning:
Content-Type text/plain; charset=utf-8
So PromiseKit has no way of knowing that the included data is meant to be JSON. You need a server that will return an application/json Content-Type. Or else you can force the JSON parse yourself, but then you're missing out on a large part of the PromiseKit benefit as you end up writing the same boilerplate code as the rest of us.
I'm attempting to upload a file using Mediafire's API. Its not clear to me what they expect in the body of the message. I'm attempting to follow the API described in https://www.mediafire.com/developers/upload.php#upload
My understanding is that some parameters are passed in a query string as part of the URL. I'm passing the session_token on the URL.
I set an HTTP header for the file size, x-filesize.
I'm setting the method to POST and sending to base url (before the query string) http://www.mediafire.com/api/upload/upload.php
Its not clear to me what should be in the body. I tried including the pure data from the file being uploaded. I've also tried adding more data to make it look like multipart form.
In either case I'm getting no response at all from the server. I'm doing this in objective-c on a Mac. The NSURLConnection request comes back with nil response and nil error. I'm using
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
The Mediafire upload API is expecting parameters to be send in the URL as the query string, GET style.
The data from the file is included in the body as a multipart form. If the body is improperly constructed, Mediafire may not return a relevant error.
Headers specified in the API are sent as headers in the body.
The 'path' parameter only appears to be honored if a uploadkey is also provided. No error is provided indicating if the path parameter was honored.
Maximum file size appears to be around 4MB.
I have an iOS app using Restkit. Most of the response bodies from the server are in XML format. However, there is a few API's that will only send a response like "Success" in text/plain format. When calling these API's I get a 200 response but restkit will throw a mapping error because it is expecting Content-Type = application/xml as is seen in the error below.
NSLocalizedDescription=Loaded an unprocessable response (200) with content type 'application/xml'} response.body=success
I am using the RKXMLReaderSerialization class to interpret the XML received from the server and this is how I register it.
[RKMIMETypeSerialization registerClass:[RKXMLReaderSerialization class] forMIMEType:#"application/xml"];
It appears from the documentation you can register multiple MIMETypes but I haven't been able to figure out how. If that is possible can someone point it out to me. If not is there a way to handle this?
UPDATE/SOLUTION
After further research and help from Wain I discovered the error above was actually stating that the response-header for content-type had a value of application/xml. This keyed restkit to try and map the response.body as an application/xml formatted body. With a response.body containing only the word "success" the response was unprocessable. I ended up pointing this out to my server guy and he corrected the response to be formatted in the MIMEType declared by the Accept header sent with the request.
You can call setAcceptHeaderWithMIMEType: on your RKObjectManager to tell it what mime types are acceptable in the response. You may need to define and register your own serialisation class too so that RestKit can execute the whole mapping workflow without errors.
I'm using NSURLConnection with sendAsynchronousRequest method (and handing the data in block).
Using above method, I'm downloading a video file from server and saving locally in cache folder.
This is working fine if the URL is valid. If the URL is invalid (that is the video is not available at given URL), it is still saving a file with the file name that I'm giving. NSError is nil and NSData object is not nil. How can I check whether the URL is valid or catch the error if URL is not there?
Check the NSURLResponse in the block, if it is an http request it is really an NSHTTPURLResponse. Check the statusCode to see the HTTP error. It may be a 404, 302, etc.
Also check the returned data, convert it to a string and see if there is anything interesting there. Sometimes there is a redirect in the returned html.