2013-12-13 59 views
1

首先,感謝大家花時間回答問題。從StackOverflow開始,我對這些年來的問題得到了如此多的快速回答。UIWebView loadRequest不會在自定義函數中觸發

我是新來的對象C和iOS編程,但從我認爲應該是一個超級簡單的應用程序開始。它收到推送通知(工作正常),並在計算出appid時重定向到網頁。

問題是,雖然我可以在viewDidLoad中將我的UIWebView加載到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 

運行時這裏編碼,雅虎頁面顯示loadRequest在didload中,但handleOpenURL仍然不會觸發。如果我將loadRequest從viewDidLoad註釋掉,則顯示一個空白頁面,並且handleOpenURL仍然不會觸發。

這裏是調試序列。 viewDidLoad中火災和接收的AppID和手動射擊handleOpenURL之前完成:

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 

任何幫助表示讚賞!

+0

你確定,你已經符合協議'UIWebViewDelegate'在正確的地方? –

+0

如何將'viewView'添加到窗口/ navController中?你已經在方法的開始處指示缺少的代碼,但不是在末尾 –

+0

Hi Rich--「theview」正在使用appdelegate中的這一行引用:「UFViewController * theview = [[UFViewController alloc] init];」 ...是的,之後沒有任何代碼。 – Joey

回答

0

您確定您只有一個UFViewController的實例嗎?

-didRegisterForRemoteNotificationsWithDeviceToken初始化一個局部變量一個新的Web視圖控制器,但我看不出它是如何得到顯示給用戶 - 一旦創建它你是不是用VC做任何事情。

這裏是我認爲可能發生的:

  1. 應用程序啓動。故事板中有一個UFViewController實例。它加載後,調用其-viewDidLoad,打印日誌語句並正確加載web視圖。
  2. 稍後,調用-didRegisterForRemoteNotificationsWithDeviceToken:方法。這個實例化一個UFViewController,並調用其上的-handleOpenUrl方法。日誌方法會觸發。但是,此控制器尚未加載到視圖層次結構中,因此其視圖從不實例化,並且其從不調用它的-viewDidLoad。 這意味着-loadRequest:被調用的webview是nil。在Objective-C中,發送消息到nil是有效的 - 與大多數其他語言不同,不會拋出任何錯誤或異常。相反,絕對沒有任何反應,因此沒有網頁加載。 UFViewController-handleOpenUrl僅由方法內的局部變量引用,所以當方法完成時,最後一次對它的強引用消失並被釋放。

要檢查這是正確的:

- 在你的VC方法NSLog(@"%@",[self description]); - 這將記錄的對象的地址,並告訴你他們是否是相同的。

- NSLog網絡控制器的視圖,以檢查它是否是nilhandleOpenURL

爲了解決你的問題,我建議使用NSNotificationAppDelegate發佈,並由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: meth OD:

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

如果您需要通過通知(例如URL),您可以使用object參數的任何信息 - 這是通過NSNotification參數的object財產呼籲VC的方法訪問。

有關Objective-C中的通知的完整文檔可以在here找到。

一些小點 - 這通常是一個壞主意,打電話給你的視圖控制器像theView而非theViewController,因爲其他人的事情(或者你6個月的時間)將結束,並誤以爲他們是UIView秒。此外,webview屬性不應以大寫字母開頭 - 通常只用於類名稱。

+0

Fnatastic答案,謝謝!我即將嘗試您的建議。感謝您對發射順序的詳細解釋......這些知識直到我有時間坐下來看書爲止。我打算做「UFViewController * theview = [[UFViewController alloc] init];/[theview handleOpenURL:url];」是得到一個指向已經創建的ViewController的指針,並調用它的handleOpenURL ...因爲我實際上需要在didRegisterForRemoteNotificationsWithDeviceToken函數中找出AppID(未包含在代碼示例中)。 – Joey

+0

Rich,您的評價是正確的!他們是兩個不同的對象。 和手動調用我的handleOpenURL函數時報告的第二個。理想情況下,在didRegisterForRemoteNotificationsWithDeviceToken中,我只想獲取已創建的WebView的句柄並調用其handleOopenURL函數。但我也會嘗試你的其他建議,看看我是否不能那樣到達那裏。謝謝! – Joey

+0

[self _UFHWebView.handleOpenURL:url]; ?? – Joey

0

這應該被稱爲「如何從appdelegate調用故事板視圖控制器方法」。答案是:

在AppDelegate.m:

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

在我上面的代碼片段,這意味着更換這些線路

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

以上的人。不同之處在於我的原始代碼將一個新的UFViewController對象實例化爲一個局部變量,而正確的代碼只是獲得了已經在故事板中創建的視圖控制器的句柄並調用其方法。

相關問題