j.doe j.doe - 1 month ago 15
Objective-C Question

When I reload UIWebView I get a Signal SIGABRT in my main.h file

Here are my files. When I click the reload button it goes into what I understand is a segfault in OBJC. I don't think it is the website but something in the main that is not being met/returned. It gives the SIGABRT in the main.m file. I've tried to enable zombies to no avail and if that is the way to go please let me know.

//
// main.m
// webKitExp
//
// Created by J.Doe on 8/14/17.
// Copyright © 2017 J.Doe. All rights reserved.
//

#import <UIKit/UIKit.h>
#import "AppDelegate.h"

int main(int argc, char * argv[]) {
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}

//
// ViewController.h
// webKitExp
//
// Created by J.Doe
// Copyright © 2017 J.Doe. All rights reserved.
//

#import <UIKit/UIKit.h>
#import <WebKit/WebKit.h>

@interface ViewController : UIViewController

@property (nonatomic, retain) IBOutlet UIWebView *webView;
@end

//
// ViewController.m
// webKitExp
//
// Created by J.Doe on 8/14/17.
// Copyright © 2017 J.Doe. All rights reserved.
//

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController
@synthesize webView;

- (void)viewDidLoad {
[super viewDidLoad];
[UIView setAnimationsEnabled:NO];
NSString *localURL = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"html"];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:[NSURL fileURLWithPath:localURL]];
[webView loadRequest:urlRequest];
}
- (IBAction)buttonClicked:(UIButton *)sender {
[webView reload];
}


- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}


@end

Answer Source

You should really be using WKWebview instead of UIWebview for apps running iOS 8+.

This is an example of using WKWebview within a UIViewController. Hitting the reload button (with or with our network connection) doesn't crash the app.

import UIKit
import WebKit

class WebviewController: UIViewController, WKNavigationDelegate {

    var wkWebview : WKWebView?

    override func viewDidLoad() {
        super.viewDidLoad()

        wkWebview = WKWebView.init(frame: self.view.bounds)
        wkWebview?.navigationDelegate = self
        self.view.addSubview(wkWebview!)

        let url = URL.init(string:"https://www.google.com")
        let urlRequest: URLRequest = URLRequest.init(url: url!)

        wkWebview?.load(urlRequest)
        // Do any additional setup after loading the view.

        let button = UIButton.init(frame: CGRect.init(x: 50, y: 200, width: 50, height: 50))
        button.setTitle("Reload", for: .normal)
        button.backgroundColor = UIColor.black
        self.view.addSubview(button)
        button.addTarget(self, action: #selector(reload), for: .touchUpInside)
        button.layer.zPosition = 101
    }

    func reload() {
        self.wkWebview?.reload()
    }


    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    public func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
        print("\(error.localizedDescription)")
    }

}

Shouldn't be too hard to convert that to Objective-C.

There is also a WKNavigationDelegate method

- (void)webView:(WKWebView *)webView
        didFailProvisionalNavigation:(WKNavigation *)navigation
        withError:(NSError *)error

which gets invoked when there is no internet access. You may want to implement that.