didFailLoadWithError being called for ios7 only
Categories:
Debugging UIWebView didFailLoadWithError on iOS 7

Explore common causes and solutions for didFailLoadWithError
being exclusively triggered on iOS 7 for UIWebView
, while working correctly on iOS 6.
Developers often encounter peculiar behavior when targeting different iOS versions. One such issue involves the UIWebView
delegate method webView:didFailLoadWithError:
being called specifically on iOS 7, even when the same code functions perfectly on iOS 6. This article delves into the common reasons behind this discrepancy and provides practical solutions to ensure your UIWebView
loads content reliably across both iOS versions.
Understanding didFailLoadWithError
The webView:didFailLoadWithError:
delegate method is invoked when a UIWebView
fails to load content. The NSError
object passed to this method provides details about the failure, including the error domain and code. On iOS 7, changes in network handling, security policies, and UIWebView
's internal implementation can lead to errors that were not present or were silently handled in iOS 6.
flowchart TD A[Start Load Request] --> B{UIWebView Internal Process} B --> C{Network Request} C --> D{Response Received?} D -- No --> E[Error Occurs] E --> F{"didFailLoadWithError:" Called} D -- Yes --> G{Content Rendered?} G -- No --> E G -- Yes --> H["didFinishLoad:" Called] F --> I[End] H --> I
UIWebView Loading Process and Error Handling
Common Causes on iOS 7
Several factors can contribute to didFailLoadWithError
being called on iOS 7 but not iOS 6. These often relate to stricter security, changes in network stack behavior, or differences in how UIWebView
handles certain types of content or requests.
- ATS (App Transport Security) - Though introduced later, similar underlying network changes can manifest. While ATS was formally introduced in iOS 9, iOS 7 already had stricter network security protocols compared to iOS 6. Non-HTTPS requests to domains that don't explicitly allow HTTP connections can fail.
- Invalid URLs or Malformed Requests: iOS 7 might be less forgiving of malformed URLs or requests that iOS 6 previously handled gracefully.
- Network Reachability Issues: Although
UIWebView
doesn't directly expose network reachability, underlying network failures are reported through this delegate method. iOS 7's network stack might report transient errors more aggressively. - Content Security Policy (CSP) Violations: If the loaded content has a CSP, iOS 7 might enforce it more strictly, leading to resource loading failures.
- Local File Access Restrictions: If you're loading local HTML files or resources, iOS 7 might have stricter sandboxing rules that prevent access to certain paths or resources.
NSError
object's code
and domain
properties within didFailLoadWithError
to get specific details about the failure. This is crucial for effective debugging.Debugging and Solutions
To effectively debug and resolve this issue, a systematic approach is required. Start by isolating the problem and then apply targeted solutions.
1. Analyze the Error Object
The NSError
object is your primary source of information. Log its code
and domain
to identify the exact nature of the failure. Common error codes include NSURLErrorDomain
errors like NSURLErrorNotConnectedToInternet
(-1009), NSURLErrorCannotFindHost
(-1003), or NSURLErrorBadURL
(-1000).
2. Verify URL and Request Validity
Ensure that the URL you are attempting to load is well-formed and accessible. Test the URL in a browser on an iOS 7 device to rule out server-side or network issues.
3. Check Network Reachability
Before loading, check if the device has an active internet connection, especially if loading remote content. You can use Reachability
(a common Apple sample code class) or NWPathMonitor
(for newer iOS versions, but the concept applies).
4. Handle HTTP vs. HTTPS
If you are loading HTTP content, consider switching to HTTPS if possible. If not, and it's a known domain, you might need to configure your Info.plist
to allow arbitrary loads for that specific domain (though this is more relevant for ATS in iOS 9+, it's good practice to be aware of network security implications).
5. Local File Access
If loading local HTML, ensure all referenced resources (CSS, JS, images) are correctly bundled and accessible relative to the main HTML file. Use loadHTMLString:baseURL:
or loadRequest:
with a fileURL
and ensure the baseURL
is set correctly for relative paths.
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
NSLog(@"UIWebView failed to load with error: %@, code: %ld, domain: %@", error.localizedDescription, (long)error.code, error.domain);
// Specific handling for common errors
if ([error.domain isEqualToString:NSURLErrorDomain]) {
switch (error.code) {
case NSURLErrorNotConnectedToInternet:
// Handle no internet connection
NSLog(@"No internet connection.");
break;
case NSURLErrorCannotFindHost:
// Handle host not found
NSLog(@"Cannot find host.");
break;
case NSURLErrorBadURL:
// Handle malformed URL
NSLog(@"Bad URL provided.");
break;
default:
break;
}
}
// Optionally display an error message to the user
// [self displayErrorMessage:error.localizedDescription];
}
Implementing didFailLoadWithError
to log and handle specific errors.
didFailLoadWithError
without understanding the root cause. Ignoring errors can lead to a poor user experience and hide critical issues in your application.Example Scenario: Loading Local HTML with Images
Consider a scenario where you load an HTML string that references local images. If the baseURL
is not set correctly, or if the images are not in the expected location relative to the base URL, iOS 7 might fail to load them, triggering didFailLoadWithError
.
Incorrect Approach (might work on iOS 6, fail on iOS 7):
<img src="myImage.png">
If myImage.png
is in your app bundle but not directly accessible via the baseURL
provided to loadHTMLString:
, iOS 7 might report an error.
Corrected Approach:
Ensure baseURL
points to the directory containing your resources, or use absolute paths if resources are in a known location.
// Assuming 'index.html' and 'myImage.png' are in the main bundle
NSString *htmlPath = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"html"];
NSString *htmlString = [NSString stringWithContentsOfFile:htmlPath encoding:NSUTF8StringEncoding error:nil];
// Correctly setting the baseURL to the main bundle's resource path
NSURL *baseURL = [[NSBundle mainBundle] resourceURL];
[self.webView loadHTMLString:htmlString baseURL:baseURL];
Loading local HTML with a correctly specified baseURL
for resource resolution.
1. Isolate the Problem
Test the UIWebView
with a very simple, known-good URL (e.g., "https://www.google.com"
) to determine if the issue is with your specific content or a general UIWebView
problem on iOS 7.
2. Log Error Details
Implement webView:didFailLoadWithError:
and log the error.code
and error.domain
. Use this information to search Apple's documentation or online resources for specific error meanings.
3. Verify Network Connectivity
Before initiating a UIWebView
load, check the device's network status. If there's no connection, you can proactively display an error message rather than waiting for didFailLoadWithError
.
4. Review URL and Content
Double-check the URL for any typos or malformations. If loading local content, ensure all paths to images, CSS, and JavaScript files are correct relative to the baseURL
.
5. Consider iOS 7 Specifics
Be mindful of iOS 7's stricter network and security policies. If loading HTTP content, ensure the server is configured correctly, or consider using HTTPS.