繁体   English   中英

UIWebView loadRequest未在自定义函数中触发

[英]UIWebView loadRequest not firing in custom function

首先,感谢大家花时间回答问题。 多年来,我从StackOverflow获得了许多快速解决问题的方法。

我是Object C和iOS编程的新手,但从我认为应该是一个超级简单的应用程序开始。 它会收到一个推送通知(工作正常),并在确定其appid后重定向到网页。

问题是,虽然我可以将UIWebView放入viewDidLoad中的loadRequest中,但相同的代码将不会在另一个函数中执行。

这是代码:

AppDelegate.m

//  UFAppDelegate.m
#import "UFAppDelegate.h"
#import "UFViewController.h"

@implementation UFAppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Add registration for remote notifications
    [[UIApplication sharedApplication] registerForRemoteNotificationTypes:
     (UIRemoteNotificationType)(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)];   
    return YES;
}

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)devToken {

    // ....

    NSString *urlString = @"http://www.google.com";
    NSURL *url = [NSURL URLWithString:urlString];
    NSLog(@"Navigating to URL: %@", url);
    UFViewController *theview = [[UFViewController alloc] init];
    [theview handleOpenURL:url];
}

@end

ViewController.h:

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

@interface UFViewController : UIViewController
- (void)handleOpenURL:(NSURL *)url;
@end

ViewController.m:

//  UFViewController.m
#import "UFViewController.h"

@interface UFViewController ()
@property (weak, nonatomic) IBOutlet UIWebView *UFHWebView;
- (void)handleOpenURL:(NSURL *)url;
@end

@implementation UFViewController
- (void)viewDidLoad
{
    [super viewDidLoad];
    NSLog(@"UFViewController.viewDidLoad started");

    // This block that assigns the url and loads it works perfectly here... but not down below.        
    NSString *urlString = @"http://search.yahoo.com/";
    NSURL *url = [NSURL URLWithString:urlString];

    NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
    [_UFHWebView loadRequest:requestObj];

    NSLog(@"UFViewController.viewDidLoad completed");
}

- (void)handleOpenURL:(NSURL *)url
{
    NSLog(@"UFViewController.handleOpenURL started");
    NSLog(@"url = %@",url);

    // The below loadRequest does not load!
    NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
    [_UFHWebView loadRequest:requestObj];
    NSLog(@"UFViewController.handleOpenURL completed");
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
{
    NSLog(@"Error - %@", error);        
}

- (BOOL) webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    return  YES;
}

@end

当按此处的代码运行时,雅虎页面从didload中的loadRequest中显示,但是handleOpenURL仍然不会触发。 如果我从viewDidLoad中注释掉loadRequest,则会显示空白页面,并且handleOpenURL仍然不会触发。

这是调试顺序。 在接收到AppID并手动触发handleOpenURL之前,viewDidLoad触发并完成:

2013-12-12 15:28:32.606 UF[5896:60b] UFViewController.viewDidLoad started
2013-12-12 15:28:32.608 UF[5896:60b] UFViewController.viewDidLoad completed
2013-12-12 15:28:32.765 UF[5896:60b] Navigating to URL: http://www.google.com
2013-12-12 15:28:32.769 UF[5896:60b] UFViewController.handleOpenURL started
2013-12-12 15:28:32.773 UF[5896:60b] url = http://www.google.com
2013-12-12 15:28:32.775 UF[5896:60b] UFViewController.handleOpenURL completed

任何帮助表示赞赏!

您确定这里只有UFViewController一个实例吗?

-didRegisterForRemoteNotificationsWithDeviceToken在局部变量中初始化了一个新的Web视图控制器,但我看不到它如何显示给用户-创建vc后,您不会对其进行任何操作。

我认为这可能正在发生:

  1. 应用启动。 您在情节UFViewController中有一个UFViewController实例。 它加载,调用-viewDidLoad ,打印日志语句,并正确加载webview。
  2. 稍后,将-didRegisterForRemoteNotificationsWithDeviceToken:方法。 这将实例化UFViewController ,并在其上调用-handleOpenUrl方法。 -handleOpenURL日志方法启动。 但是,此控制器尚未加载到视图层次结构中,因此永远不会实例化其视图,也永远不会调用其-viewDidLoad 这意味着正在调用-loadRequest:-loadRequest:nil 在Objective-C中,将消息发送为nil是有效的-与大多数其他语言不同,不会引发任何错误或异常。 相反,绝对没有任何反应,因此没有Web负载。 UFViewController中的-handleOpenUrl仅由方法内的局部变量引用,因此,在方法完成时,对该方法的最后一个强引用将消失并被释放。

要检查是否正确:

NSLog(@"%@",[self description]); 在您的vc方法中-这将记录对象的地址并告诉您它们是否相同。

- NSLog网络控制器的视图,以检查它是否是nilhandleOpenURL

为了解决您的问题,我建议使用AppDelegate发布的NSNotification并由完全实例化的UFViewController监听。 因此,在vc中,您可以执行以下操作:

[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(handleRegistration:) name:@"HandleRegistrationNotification" object:nil];

然后实现handleRegistration方法:

-(void)handleRegistration:(NSNotification*)notification
{
     //your handleOpenUrl code 
}

并且

-(void)dealloc
{
    [[NSNotificationCenter defaultCenter]removeObserver:self name:@"HandleRegistrationNotification" object:nil];
}

(这一点很重要,因为否则在取消分配vc时可能会崩溃)

然后,在-didRegisterForRemoteNotifications:方法中:

[[NSNotificationCenter defaultCenter]postNotificationName:@"HandleRegistrationNotification" object:nil];

如果您需要通过通知传递任何信息(例如url),则可以使用object参数-在vc上通过NSNotification参数的object属性调用的方法中可以访问该参数。

有关Objective-C中通知的完整文档,请参见此处

有几点要点-将视图控制器之类的东西theView而不是theViewController通常是一个坏主意,因为其他人(或您六个月后的时间)最终会认为它们是UIView 同样,webview属性不应以大写字母开头-通常仅用于类名。

这应该称为“如何从appdelegate调用情节提要viewviewler方法”。 答案是:

在AppDelegate.m中:

#import "UFViewController.h"
...
UFViewController *rootViewController = (UFViewController*)self.window.rootViewController;
[rootViewController handleOpenURL:url];

在上面的代码段中,这意味着替换这些行

UFViewController *theview = [[UFViewController alloc] init];
[theview handleOpenURL:url];

与上面的那些。 区别在于我的原始代码将一个新的UFViewController对象实例化为一个局部变量,而正确的代码只是获取了已在情节提要中创建的视图控制器的句柄并调用了它的方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM