2016-03-07 77 views
2

我剛剛在我的應用程序中使用教程/示例代碼設置了WCConnectivity,我覺得我已經正確實施了。我沒有使用模擬器來測試。出於某種原因,即使所有設置都正確,didReceiveApplicationContext也不會在手錶應用程序中調用。didReceiveApplicationContext不被調用

我試着在ExtensionDelegate中的WatchKit應用程序的接口控制器中調用,並使用NSUserDefaults來設置接口控制器數據。

iOS應用

ViewController.m

- (void) viewDidLoad{ 
if ([WCSession isSupported]) { 
    WCSession *session = [WCSession defaultSession]; 
    session.delegate = self; 
    [session activateSession]; 
    } 
} 

-(void) saveTrip{ 
NSMutableArray *currentTrips = [NSMutableArray arrayWithArray:[self.sharedDefaults objectForKey:@"UserLocations"]]; 

NSData *data = [NSKeyedArchiver archivedDataWithRootObject:newLocation]; 
[currentTrips addObject:data]; 
[self.sharedDefaults setObject:currentTrips forKey:@"UserLocations"]; 
[self.sharedDefaults synchronize]; 

WCSession *session = [WCSession defaultSession]; 
NSDictionary *applicationDict = [[NSDictionary alloc] initWithObjects:@[currentTrips] forKeys:@[@"UserLocations"]];; 
[session updateApplicationContext:applicationDict error:nil]; 
} 

關注擴展代碼

ExtensionDelegate.m

- (void)applicationDidFinishLaunching { 
if ([WCSession isSupported]) { 
    WCSession *session = [WCSession defaultSession]; 
    session.delegate = self; 
    [session activateSession]; 
} 
} 
- (void)session:(nonnull WCSession *)session didReceiveApplicationContext:(nonnull NSDictionary<NSString *,id> *)applicationContext { 
self.places= [applicationContext objectForKey:@"UserLocations"]; 
[[NSUserDefaults standardUserDefaults] setObject:self.places forKey:@"UserLocations"]; 
[[NSUserDefaults standardUserDefaults] synchronize]; 
} 

InterfaceController.m

- (void)willActivate { 
[super willActivate]; 
self.placesData = [NSMutableArray arrayWithArray:[[NSUserDefaults standardUserDefaults] objectForKey:@"UserLocations"]]; 
[self loadData]; 
} 
+0

有沒有名爲'didReceiveApplicationWithContext'方法。發佈您的實際代碼。 – dan

+0

@dan更新了原文 – emleeh

回答

2

如果它不工作,它可能無法正確執行。

第一眼的幾個問題:

  • 在iOS應用中,你得到的共享會話的引用,並激活它,但不要在局部變量分配給任何財產上的視圖控制器。這意味着一旦viewDidLoad退出,您的本地變量將超出範圍。您還需要在您的手錶擴展程序中進行更正。

  • saveTrip中,您再次創建另一個本地會話,該會話未激活且沒有任何委託。您需要使用您之前設置並激活的第一個會話。

  • 在您的手錶上,您保存了接收到的數據,但您的界面控制器不會知道應該加載和顯示的新數據。

一些提示:

  • 如果在安裝和激活application:didFinishLaunchingWithOptions會議,這將是可用的應用程序範圍內(在您的應用程序的生命週期中更早地激活)。

  • 您應該檢查您的會話是否有效,因爲手錶可能未配對,或者手錶應用程序可能未安裝。這裏是a good (Swift) tutorial that covers those cases, and also uses a session manager,以便更輕鬆地支持在整個應用程序中使用Watch Connectivity。

  • 您可能希望將較少/較輕的數據傳遞到手錶,而不是嘗試處理歸檔自定義對象數組。

  • 另一方面,你想要做什麼NSUserDefaults是非常複雜的。這實際上意味着在推出期間堅持偏好。將它用作在擴展和控制器之間來回傳遞模型的方式並不合適。

+0

謝謝。我只是非常自由地使用NSUserDefaults,因爲這是應用程序的beta版本,而在實際的應用程序中,我將使用數據庫和API調用。我認爲這可能與我的實際項目有關 - 即使在關閉Watch App時,我的session.reachable也是如此。我也收到一個錯誤,表示手錶二進制文件沒有連接到手錶擴展,這又是關係。我可能只需要開始一個新項目並重新設置。 – emleeh

4

它可能被證明是處理任何錯誤有用的,所以改變:

[session updateApplicationContext:applicationDict error:nil]; 

NSError *error;  
if (![session updateApplicationContext:applicationDict error:&error]) { 
    NSLog(@"updateApplicationContext failed with error %@", error); 
} 
1

我有同樣的問題和解決。 我忘了在Watch擴展中添加WatchConnectivity框架。

0

對我來說,這是兩件事情:

  1. 在字典中傳遞無效值。甚至不能通過NSNull()來表示零值。如果您的數據不能在plist中表示,則失敗。
  2. 如果字典不改變,隨後以updateApplicationContext調用不會觸發對didReceiveApplicationContext相應的呼叫。要強制更新,您可以向有效負載添加UUID,例如

    context["force_send"] = UUID().uuidString