2013-02-10 27 views
11

Xin chào, Tôi đang viết ứng dụng cần trả lời với cập nhật giao diện người dùng và thay đổi trạng thái nội bộ khi sử dụng thông báo cục bộ để mở nó. Tôi đang sử dụng cốt truyện và tôi đã thiết lập bộ điều khiển giao diện chính của tôi để quan sát tình trạng thay đổi:ứng dụng: didFinishLaunchingWithOptions: thông báo kích hoạt trước khi bộ điều khiển đích được tạo ra

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    // ... 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(resumeByNotification:) name:@"Resume" object:nil]; 
} 

Trong đại biểu ứng dụng của tôi, tôi có điều này:

- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification 
{ 
    if (application.applicationState == UIApplicationStateInactive) 
    { 
     [[NSNotificationCenter defaultCenter] postNotificationName:@"Resume" object:self userInfo:notification.userInfo]; 
    } 
} 

Và điều này chỉ hoạt động tốt: nếu ứng dụng là chạy ở chế độ nền, trình điều khiển chế độ xem sẽ chặn thông báo và phản ứng tương ứng. (Nếu ứng dụng đang chạy ở nền trước, nó bị bỏ qua vì giao diện người dùng đang được xử lý trực tiếp.)

Sự cố xảy ra khi ứng dụng đã bị giết và nhận được thông báo. Tôi đã viết này trong phương thức didFinishLaunchingWithOptions, làm cho điện thoại rung như một kỹ thuật debug nhanh :), và tôi làm nhận được thông báo:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{ 
    UILocalNotification *localNotification = launchOptions[UIApplicationLaunchOptionsLocalNotificationKey]; 
    if (localNotification) 
    { 
     [[NSNotificationCenter defaultCenter] postNotificationName:@"Resume" object:self userInfo:localNotification.userInfo]; 
     AudioServicesPlaySystemSound(kSystemSoundID_Vibrate); 
    } 

    return YES; 
} 

Chiếc điện thoại KHÔNG rung để thông báo là có, nhưng nó doesn dường như không kích hoạt người quan sát. Tôi cho rằng điều này là do phương thức didViewLoad của trình điều khiển xem chưa được gọi. Tôi không chắc chắn làm thế nào để làm việc này xung quanh. Tôi cho rằng tôi có thể sử dụng phương thức instantiateViewControllerWithIdentifier: của UIStoryboard để đảm bảo rằng bộ điều khiển xem thực sự ở đó, nhưng tôi sẽ không nhận được một trường hợp "bổ sung" của nó, ngoài ra nó sẽ được tạo ra bởi chu kỳ sống của bảng phân cảnh ? Đánh giá từ những gì trên các tài liệu tham khảo lớp học nói, nó không chính xác có nghĩa là để làm điều này loại điều.

Tôi có thiếu điều gì đó hiển nhiên ở đây không? Trong thực tế, cách tiếp cận của tôi là đúng đối với loại tình huống này?

Cảm ơn!

Trả lời

11

Trình điều khiển chế độ xem không tải chế độ xem của nó cho đến khi có gì đó yêu cầu nó cho chế độ xem của nó. Vào lúc khởi động, điều đó thường xảy ra sau khi trả về application:didFinishLaunchingWithOptions:.

Bạn có thể thắc mắc tại sao. Câu trả lời là bạn có thể khởi tạo một số bộ điều khiển xem lúc khởi động, một số trong số đó bị ẩn. Ví dụ: nếu trình điều khiển chế độ xem gốc của cửa sổ là UINavigationController, bạn có thể tải trình điều khiển điều hướng bằng một bộ điều khiển chế độ xem (ngăn xếp mà người dùng đã đẩy lần cuối cùng ứng dụng chạy). Chỉ bộ điều khiển chế độ xem trên cùng của ngăn xếp này mới hiển thị, do đó không cần phải tải chế độ xem của các bộ điều khiển chế độ xem khác. Hệ thống đợi cho đến khi application:didFinishLaunchingWithOptions: trả về trước khi tải bất kỳ chế độ xem nào để chỉ các lượt xem cần thiết mới được tải.

Vì vậy, một cách để giải quyết vấn đề của bạn đơn giản là yêu cầu bộ điều khiển xem cho chế độ xem của nó, do đó buộc phải tải. Nếu điều khiển xem của bạn là quan điểm điều khiển gốc của cửa sổ, bạn có thể làm theo cách này:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{ 
    UILocalNotification *localNotification = launchOptions[UIApplicationLaunchOptionsLocalNotificationKey]; 
    if (localNotification) { 
     [[self.window rootViewController] view]; 
     [[NSNotificationCenter defaultCenter] postNotificationName:@"Resume" object:self userInfo:localNotification.userInfo]; 
     AudioServicesPlaySystemSound(kSystemSoundID_Vibrate); 
    } 

    return YES; 
} 

Một cách giải quyết khác nhau sẽ được bắt đầu quan sát thông báo trong phương pháp điều khiển xem của bạn initWithCoder::

- (id)initWithCoder:(NSCoder *)aDecoder { 
    if (self = [super initWithCoder:aDecoder]) { 
     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(resumeByNotification:) name:@"Resume" object:nil]; 
    } 
    return self; 
} 

này được gọi khi bộ điều khiển xem được khởi tạo từ MainStoryboard, điều này xảy ra trước thông báo application:didFinishLaunchingWithOptions:.

+0

Cảm ơn bạn, bằng cách sử dụng 'initWithcoder:' hoạt động như một sự quyến rũ. Tất cả các bước này trong vòng đời của một đối tượng có thể khá khó hiểu. :) – Jollino

+0

Cảm ơn, điều này cũng hoạt động nếu bạn đang sử dụng thông báo đẩy thay vì thông báo địa phương và không có bảng phân cảnh. Chỉ cần sử dụng phương thức 'init'. – yoeriboven

+0

['init (coder:)'] (https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Protocols/NSCoding_Protocol/index.html#//apple_ref/occ/intfm/NSCoding/initWithCoder :) –

Các vấn đề liên quan