Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/114.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 当从内部调用模式视图时,UIWebView应仅激发一次StartLoadWithRequest_Iphone_Ios_Objective C_Ipad_Iphone Web App - Fatal编程技术网

Iphone 当从内部调用模式视图时,UIWebView应仅激发一次StartLoadWithRequest

Iphone 当从内部调用模式视图时,UIWebView应仅激发一次StartLoadWithRequest,iphone,ios,objective-c,ipad,iphone-web-app,Iphone,Ios,Objective C,Ipad,Iphone Web App,我的应用程序有一部分是用JS编写的,在WebView中运行。我使用UIWebView shouldStartLoadWithRequest方法捕获http请求,作为JS和obj-c之间通信的一种方式。在我尝试从shouldStartLoadWithRequest方法内部在webview上加载一个模态视图控制器之前,这是非常有效的。一旦发生这种情况,就不再调用shouldStartLoadWithRequest。有时,我需要关闭这个模态视图控制器,返回webview并执行一些操作,然后重新显示模态

我的应用程序有一部分是用JS编写的,在WebView中运行。我使用UIWebView shouldStartLoadWithRequest方法捕获http请求,作为JS和obj-c之间通信的一种方式。在我尝试从shouldStartLoadWithRequest方法内部在webview上加载一个模态视图控制器之前,这是非常有效的。一旦发生这种情况,就不再调用shouldStartLoadWithRequest。有时,我需要关闭这个模态视图控制器,返回webview并执行一些操作,然后重新显示模态控制器。模态控制器第一次出现时很好,然后我将其关闭,并尝试通过从javascript导航到URL来再次显示它,它将不再显示自己。shouldStartLoadWithRequest中的NSLogs永远不会运行

在我的javascript中,我执行以下操作:

 window.location='myapp:whateverMethod';
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
    NSString *requestString = [[request URL] absoluteString];
    NSLog(@"REQUEST URL: %@", requestString);
    if([requestString hasPrefix:@"myapp:"]) {
        NSArray *components = [requestString componentsSeparatedByString:@":"];
        NSString *function = [components objectAtIndex:1];
        if([self respondsToSelector:NSSelectorFromString(function)]) {
            [self performSelector:NSSelectorFromString(function)];
        }
        return NO;
    }
    return YES;
}

-(void) whateverMethod {
    NSLog(@"whateverMethod called!");
    // This is a quick way to grab my view controller from the storyboard, so assume it exists
    UIViewController *splash = [self.storyboard instantiateViewControllerWithIdentifier:@"splashViewController"];
    [self presentModalViewController:splash animated:NO];
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2 * NSEC_PER_SEC), dispatch_get_current_queue(), ^{
        [self dismissModalViewController:splash animated:NO];
    });
}
目标c代码如下所示:

 window.location='myapp:whateverMethod';
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
    NSString *requestString = [[request URL] absoluteString];
    NSLog(@"REQUEST URL: %@", requestString);
    if([requestString hasPrefix:@"myapp:"]) {
        NSArray *components = [requestString componentsSeparatedByString:@":"];
        NSString *function = [components objectAtIndex:1];
        if([self respondsToSelector:NSSelectorFromString(function)]) {
            [self performSelector:NSSelectorFromString(function)];
        }
        return NO;
    }
    return YES;
}

-(void) whateverMethod {
    NSLog(@"whateverMethod called!");
    // This is a quick way to grab my view controller from the storyboard, so assume it exists
    UIViewController *splash = [self.storyboard instantiateViewControllerWithIdentifier:@"splashViewController"];
    [self presentModalViewController:splash animated:NO];
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2 * NSEC_PER_SEC), dispatch_get_current_queue(), ^{
        [self dismissModalViewController:splash animated:NO];
    });
}
此时,我的网络视图仍然可见。我在我的webapp中从一个页面导航到另一个页面,所有javascript在其中都工作得很好,但是webview的“shouldstartoadwithrequest”委托方法不再被调用。我不明白为什么。有人有什么想法吗?

我注意到没有设置window.location属性。相反,它有两个选项:要么创建一个iframe并将iframe的src设置为该url,要么创建一个XMLHttpRequest对象,例如在iOSExec()函数中:

    if (bridgeMode) {
        execXhr = execXhr || new XMLHttpRequest();
        // Changeing this to a GET will make the XHR reach the URIProtocol on 4.2.
        // For some reason it still doesn't work though...
        execXhr.open('HEAD', "file:///!gap_exec", true);
        execXhr.setRequestHeader('vc', cordova.iOSVCAddr);
        if (shouldBundleCommandJson()) {
            execXhr.setRequestHeader('cmds', nativecomm());
        }
        execXhr.send(null);
    } else {
        execIframe = execIframe || createExecIframe();
        execIframe.src = "gap://ready";
    }

也就是说,使用类似的东西而不是自己尝试滚动它(即使只是嵌入他们的视图控制器)可能是有益的,因为它们处理了webview代理带来的许多头痛问题。

我也遇到了同样的问题,但与使用href=“#”锚相关


关于widow.location,该线程中有更多的答案,因此您可能会很幸运。

查看了Cordova,他们有自己的排队系统,而不是真正的帮助。但是

不听话的媒体的回答给了我一个想法。为什么不试试window.location.hash而不是window.location呢

现在,一些用于日志记录的JS代码是:

function sendMsgToNative(msg)
{
    window.location.hash = '~cmd~' + msg;
}
console.log = function (msg) { sendMsgToNative('log~js ' + msg); };
而Objective-C代码是:

NSString *req = [request.URL absoluteString];
NSArray *components = [req componentsSeparatedByString:@"~"];

// Check for your protocol
if ([components count] > 1 && [(NSString *)[components objectAtIndex:1] isEqualToString:@"cmd"])
{
    // Look for specific actions
    if ([(NSString *)[components objectAtIndex:2] isEqualToString:@"log"])
    {
        NSString *logStr = [(NSString *)[components objectAtIndex:3] stringByReplacingPercentEscapesUsingEncoding: NSUTF8StringEncoding];
        LOGI("%@", logStr);
    }
}
您得到了完整的URL,包括“http:…”,因此我选择了tilde而不是冒号,并增加了索引。 现在,您可以随意登录所有日志,并发送任意数量的命令,这些命令都将通过:-)

我(尴尬地)今天花了几个小时来完成这项工作,并意识到在我的视图中消失了:我将UIWebViewDelegate设置为零


我所需要做的只是在模式被取消后,重新设置UIWebViewDelegate,然后一切都恢复正常

有趣。实际上,我已经尝试过使用这两种方法创建请求,并且得到了完全相同的结果(shouldstarting将执行,直到出现一个模式窗口,然后停止)。用科尔多瓦试一试,看看是否会有同样的结果。这感觉像是iOS中的细微差别,但我可能错了。在没有找到一个适合本项目需要的解决方案后,我最终使用CSS动画等模仿了webview内部的模式视图(与模式视图的外观非常接近),因此不再需要隐藏webview。