Is it possible to send a hash tag to a file url in

2020-06-09 04:28发布

I want to load a html page from a file, and append a hash tag to it. Is this possible?

I have tried

NSString *filePath = [[NSBundle mainBundle] pathForResource:@"someFile" ofType:@"html"];  
NSURL *fileUrl = [NSURL fileURLWithPath:[filePath stringByAppendingFormat:@"#hashtag"]];
[self.webView loadRequest:[NSURLRequest requestWithURL:fileUrl]];    
NSLog(@"fileUrl = %@, reachable? %d", fileUrl, [fileUrl checkResourceIsReachableAndReturnError:nil]);

but this tries to look for the file someFile.html%23hashtag, which can't be found. Is there a way to add the hash after the NSURL object is created?

I've also tried loading the file into a string and using loadHTMLString:

NSString *filePath = [[NSBundle mainBundle] pathForResource:@"someFile" ofType:@"html"];
NSString *fileContents = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
[self.webView loadHTMLString:fileContents baseURL:[NSURL URLWithString:@"http://someFile.html#hashtag"]];

Here the hash tag does work, but my javascript references inside the html don't work. A follow on question from this approach would be, how do I reference javascript files from html loaded in as a string in a UIWebView, ie, what is the base url?

A hack I can think of is to just put all my javascript files inline in the html and load it as a string, but I'm thinking there must be a better way!

7条回答
疯言疯语
2楼-- · 2020-06-09 05:08

This is how I do it in my code. I append the hashmark to the NSString, then I turn it into an NSURL using fileURLWithPath. Then I replace all instances of %23 back into a #. Its all explained in the code below, but let me know if you have any questions.

NSString *filePath = [[NSBundle mainBundle] pathForResource:@"someFile" ofType:@"html"];    
    NSString *filePathWithHash = [NSString stringWithFormat:@"%@#yourDesiredHashTagHere",filePath];
    NSURL *theURL = [NSURL fileURLWithPath:filePathWithHash];
    //NSURL turns the # into %23 when using fileURLWIthPath. So we need to change it back:
    NSString *finalURLString = [[NSString stringWithFormat:@"%@",theURL] stringByReplacingOccurrencesOfString:@"%23" withString:@"#"];
    //Then we need to change it back to an NSURL
    NSURL *finalURL = [NSURL URLWithString:finalURLString];
    //And finally we load this in the webView
    [theWebView loadRequest:[NSURLRequest requestWithURL:finalURL]];
查看更多
够拽才男人
3楼-- · 2020-06-09 05:10

I've not tried this but how about loading the file normally without the hashtag and implementing the UIWebViewDelegate with something like this?

- (void)webViewDidFinishLoad:(UIWebView *)webView {
   [webView stringByEvaluatingJavaScriptFromString:@"window.location.href = '#hashtag';"];
}

References:

查看更多
Root(大扎)
4楼-- · 2020-06-09 05:12

In Swift (with WKWebView):

override func viewDidLoad() {
    super.viewDidLoad()

    webView.navigationDelegate = self
}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    if let baseURL = Bundle.main.url(forResource: "myFile", withExtension: "html") {

        //Load the main page and allow access to its directory
        webView.loadFileURL(baseURL, allowingReadAccessTo: baseURL.deletingLastPathComponent())
    }

}

func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {


      let anchor = "#myanchor"

       //Use javascript to jump to the location
       webView.evaluateJavaScript("location.href = '" + anchor + "'", completionHandler: nil)


}
查看更多
Explosion°爆炸
5楼-- · 2020-06-09 05:17

I think you have to add the hash after you create the file URL

Does it work if you change

NSURL *fileUrl = [NSURL fileURLWithPath:[filePath stringByAppendingFormat:@"#hashtag"]];

to something like:

NSString *urlString = [[NSURL fileURLWithPath:filePath] absoluteString];
NSURL *fileUrl = [NSURL URLWithString:[urlString stringByAppendingString:@"#hashtag"]];
查看更多
淡お忘
6楼-- · 2020-06-09 05:21

You should be able to intercept the NSURLRequest, cast it to a NSMutableURLRequest, then change the URL as follows. All this would happen in shouldStartLoadWithRequest. Make sure you set the UIWebView delegate.

- (void) viewDidLoad
{
    self.webView.delegate = self;

    NSString *filePath = [[NSBundle mainBundle] pathForResource:@"someFile" ofType:@"html"];  
    NSURL *fileUrl = [NSURL fileURLWithPath:filePath];
}

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    //Make sure the request is mutable
    if(![request isKindOfClass:[NSMutableURLRequest class]])
        [NSException raise:@"Need to change the request, but can't" format:@""];

    NSMutableURLRequest* mutableRequest = (NSMutableURLRequest*)request;    
    NSString* newUrl = [NSString stringWithFormat:@"%@#hashtag", [[request URL] absoluteString]];
    [mutableRequest setURL:[NSURL URLWithString:newUrl]];    

    return YES;
}

I haven't run into any cases where the request wasn't mutable, but who knows.

Or you may want to set the hash in the original URL (like you were doing), then replace the first occurrence of %23 with # in shouldStartLoadWithRequest.

查看更多
神经病院院长
7楼-- · 2020-06-09 05:29

An addition to @xiang's answer. Below the swift version if you're working with local html files in your app:

let urlString = "relative/path/to/your/index.html"
let anchorString = "#your-anchor"
let baseURL:NSURL? = NSBundle.mainBundle().URLForResource(urlString, withExtension: nil, subdirectory: nil)
if let url:NSURL? = NSURL(string: anchorString, relativeToURL: baseURL) {
    // Do something with your URL
}
查看更多
登录 后发表回答