Random error on loading a static resource with a UIWebView - ios

I'm using a UIWebView to load a static resource shipped within my application bundle. Sometimes, I have no clear what the problem could be, I receive the following error within the delegate method - (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
NSUnderlyingError = "Error Domain=kCFErrorDomainCFNetwork Code=-1001
The resource is loaded through a NSURLRequest where I set up a timeout interval of 10 seconds, but that interval is not followed. In fact, in the debug console I'm able to see that the error delegate is called after about 2 seconds.
NSURL *htmlFile = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"root" ofType:#"html"] isDirectory:NO];
NSURLRequest* htmlRequest = [NSURLRequest requestWithURL:htmlFile cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:10.0];
[webView loadRequest:htmlRequest];
The fact is that I cannot always replicate the problem I have. Any suggestions?
P.S. I'm working with an app that runs from 4.3. The problem is also with iOS 7.

According to apple CFNetwork Error Codes Reference this code is a timeout error:
kCFURLErrorTimedOut = -1001
Timeout are not always easy to reproduce most likely you should extend the timeout value when you init the NSURLRequest.
According to the same docs you can query the object for additional information.
For example:
if (CFEqual(CFErrorGetDomain(err), kCFErrorDomainCFNetwork) && CFErrorGetCode(err) == kCFHostErrorUnknown) {
CFDictionaryRef userInfo = CFErrorCopyUserInfo(err);
CFNumberRef number = (CFNumberRef) CFDictionaryGetValue(userInfo, kCFGetAddrInfoFailureKey);
...
CFRelease(userInfo);
}

I suppose that the resource you are looking for is not available. Be sure that the path is correct (ios is case sensitive) and if you are downloading some contents from internet be sure that the download is completed and the file is copied from the temporary folder to the final destination.

Related

WCErrorDomain 7013 when trying to send image using Watch OS 2

I´m testing Apple Watch OS 2 and I´m trying to send a image from the application to the watch. According to Apple, I shall use WCSession transferFile to do this.
Use the transferFile:metadata: method to transfer files in the background. Use this method in cases where you want to send more than a simple dictionary of values. For example, use this method to send images or file-based documents.
for example:
NSString *string = [[NSBundle mainBundle] pathForResource:#"my_image" ofType:#"png"];
NSURL *path = [NSURL URLWithString:string];
[[WCSession defaultSession] transferFile:path metadata:#{#"meta1":#"meta2"}];
It all looks ok in the debugger, the path is correct and the file is accessible (checked with NSFileManager) and readable.
However, everytime I try I get a callback to the didFinishFileTransfer function, including an error:
Error Domain=WCErrorDomain Code=7013 "The operation couldn’t be completed. (WCErrorDomain error 7013.)"
Looking up the error:
WCErrorCodeFileAccessDenied
An error indicating that a file could not be transferred because it was inaccessible.
Available in watchOS 2.0 and later.
It seems the file is not accessible by the send function? I have tried things like resaving the file to another directory etc, but nothing seems to work.
Anyone got an idea?
The URL you are creating is not a fileURL. Try:
NSURL *path = [NSURL fileURLWithPath:string];
I managed to solve the issue!
It was because my path did not start with file://
The following code worked just fine:
NSString *string = [[NSBundle mainBundle] pathForResource:#"my_image" ofType:#"png"];
string = [NSString stringWithFormat:#"file://%#", string];
NSURL *path = [NSURL URLWithString:string];
[[WCSession defaultSession] transferFile:path metadata:#{#"meta1":#"meta2"}];
So it´s quite picky regarding the path.

WKWebView gives SecurityError when bundling html and javascript with app

We are trying to migrate a hybrid app from UIWebView (iOS < 8) to WKWebView (iOS 8), but we are getting SecurityErrors when trying to store stuff using the DOM WebDatabase API (i.e. 'web sql databases').
The following throws an error if the index.html has been loaded from a bundled file with the app
// throws SecurityError: DOM Exception 18
var db = openDatabase('mydb', '1.0', 'key value store', 1);
The same code works fine with UIWebView. I can fallback to using Local Storage for some reason, but using WebSQL databases is a no go. I can only speculate that this has something to do with the same origin policy or something related.
The funny thing is that loading index.html from the network works fine :-/
Any clues as to how I can work around this? Any options to set on the WKWebView that fixes it?
This is how we load the web related stuff:
NSString *htmlPath = [[NSBundle mainBundle] pathForResource:#"index" ofType:#"html"];
NSURL *baseURL = [NSURL fileURLWithPath:htmlPath];
NSURLRequest *request = [NSURLRequest requestWithURL:baseURL];
WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
[config.userContentController addScriptMessageHandler:self.myCallbacks name:#"NativeApp"];
self.webView = [[WKWebView alloc] initWithFrame:self.view.frame configuration:config];
[self.webView loadRequest:request];
The html file simply loads a javascript file that has a relative path, "myCode.js".
There is an issue (OpenRadar) with WKWebView in iOS 8.0 (and 8.1 B1, I think) that prevents it from loading local files. It might be affecting local storage too. See this question for more details.
You can fix this by adding the following method to the UIDelegate of your WKWebView.
- (void) _webView:(WKWebView *)webView
decideDatabaseQuotaForSecurityOrigin:(WKSecurityOrigin *)securityOrigin
currentQuota:(unsigned long long)currentQuota
currentOriginUsage:(unsigned long long)currentOriginUsage
currentDatabaseUsage:(unsigned long long)currentUsage
expectedUsage:(unsigned long long)expectedUsage
decisionHandler:(void (^)(unsigned long long newQuota))decisionHandler {
decisionHandler(1024*1024*50); //default to 50MB
}
It gives all databases a quota of 50MB, instead of the default of 0 which allows them to be opened. This behavior isn't documented, so I don't know where Apple stands with this.
Also, it appears this issue will be fixed in iOS 10.
I've made a 'plugin' that allows you to use WebSQL (more an implementation of it) in the WKWebView. It can be found here
https://github.com/ajwhiteway/WKWebSQL
import WKWebSQL
.
.
.
var webView = WKWebView(frame: view.frame, configuration: WKWebViewConfiguration())
WKWebSQL.LoadPlugin(webView)
To get it loaded into the page. Versioning isn't really supported at this time. Feel free to add it.

Encrypted pdf files crashes on UIWebView in iOS 7

I am trying to open pdf files in my UIWebView in below steps.
self.docViewer is a strong property.
self.docViewer.delegate = self;
NSURLRequest *urlReq = [NSURLRequest requestWithURL:[NSURL fileURLWithPath:docurl]];
[self.docViewer loadRequest:urlReq];
It opens normal pdf files and password protected files with no issues.
When the file is an encrypted one, it crashes after executing delegate methods.
- (void)webViewDidFinishLoad:(UIWebView *)webView
with below log
unsupported security handler `Adobe.PubSec'.
FlateDecode: decoding error: incorrect header check.
FlateDecode: decoding error: incorrect header check.
unsupported security handler `Adobe.PubSec'.
I checked all possible ways mentioned in suggested treads. I didn't find any solution.
Could anyone please help me out of this crash.Thanks a Lot

Phonegap / Cordova ios load remote url how to fallback to local index.html on error?

I use remote url for contents in my cordova, I use appcache to make it work offline - now the problem is handling the initial load before the appcache gets initialized.
In Android I let the device fallback to the local index.html - this could be informative eg. letting the user know that they have to be online to finalize the install.
// On error show default message page...
public void onReceivedError( int errorCode, String description, String failingUrl)
{
super.loadUrl("file:///android_asset/www/index.html");
return;
}
Question: "How do I accomplish the same in IOS?"
Dont have to write the code for me - hints to files and api would be appreciated
You can you the UIWebViewDelegate methods to detect that your remote content loading has failed to load. For example :
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
{
// here you can either check for the error type or for the url that has failed to load
if([webView.request.url.absoluteString isEqualToString:#"your_remote_url")]
{
NSURL *url = [NSURL urlWithString:#"your_local_url"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[webview loadRequest:request];
}
}
Since you simply want to do some error handling, one solution to this would be to do a SubView, and load it from whatever URL you need it from.
You can find a guide on how to do this, here:
http://docs.phonegap.com/en/3.0.0/guide_platforms_ios_webview.md.html#iOS%20WebViews
Of course, this gets called from the native part :)
Hope that helped!

NSURLConnection always failing after restarting app

I realize this is a vague question, but I'm wondering if anyone else has observed this. Here is my code for calling the NSURLConnection
// Get data from server
NSString *host = #"www.hostname.com";
NSString *urlString = [NSString stringWithFormat:#"/theRestOfTheURL"];
NSURL *url = [[NSURL alloc] initWithScheme:#"http" host:host path:urlString];
DLog(#"URL is %#", url);
// Create the NSMutableData to hold the received data.
// receivedData is an instance variable declared elsewhere.
receivedData_ = [[NSMutableData data] retain];
NSURLRequest *theRequest=[NSURLRequest requestWithURL:url
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:15.0];
// create the connection with the request
// and start loading the data
self.powerPlantDataConnection = [[[NSURLConnection alloc] initWithRequest:theRequest delegate:self] autorelease];
[url release];
When I first load the app it works fine, and I can call it repeatedly without any problem. But if I close the app and reopen it, the
(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
delegate method gets called every time, with a request timed out error message. I have two different view controllers where I am making calls to two different URLS, and both of them fail every time after closing and reopening the app.
Can anyone think of any reason why this might be happening? I'm not sure where to start looking. What could be the cause of a request timed out error? There should be nothing wrong with the request since it works when I first run the app.
Edited to add that it seems I only have this problem on my device, not on the simulator.
Wish you had shared some chrash log(especially with clear definition like
[error localizedDescription] class method..)
As you have said it is going to timeout(your request). and since your way of creating the objects is too messy, you make the work bigger for your system. I suggest using GCD when downloading data and especially in situations like yours, having different interfaces and urls..
A suggestion
You can create your url object like this:
NSURL *url = [NSURL urlWithString:[NSString stringWithFormat:#"http://%#/%#?key1=%#&key2=%#", yourDomain, targetFile, value1, value2]];
I switched over to using ASIHTTPRequest, which improved things but I would still get stuck in situations where I was getting timed out errors every time I tried to refresh. I looked and asked around, and eventually found that disabling calls to TestFlight solved my issue. More information here:
ASIHTTPRequest request times out
and here:
github.com/pokeb/asi-http-request/issues/320

Resources