1. 程式人生 > >Apple Watch開發的幾個小問題

Apple Watch開發的幾個小問題

20160522

Q1 如何在除錯AppleWatch的時候對watch程式打斷點
  1. 在Xcode的Target選擇AppleWatch程式

  2. Watch應用啟動之後再開啟iPhone模擬器中的程式,然後回到Xcode,選擇選單裡的Debug->Attach to Process by PID or name ,填寫apple watch extension 的bundle identifier

斷點就可以生效了

Q2 WatchKit 架構變化

在 watchOS 1 做過開發的人,都應該熟悉如下這張圖:

如上圖所示,在 watchOS 1 上面做開發,Apple Watch 應用程式由兩部分構成:Watch App 和 WatchKit 擴充套件。

Watch App 是一個執行在 Apple Watch 中的可執行檔案。它包括 storyboard 和渲染螢幕時所需的資原始檔。

WatchKit 擴充套件則是執行在 iPhone 上的可執行檔案。包括管理應用程式介面的邏輯程式碼,以及處理使用者的互動操作。

那麼,在 watchOS 2 中,WatchKit 的架構發生了比較重大的變化,我們先來看看下面這張圖:

從上面的圖中,可以很明顯地看出,蘋果把原來執行在 iPhone 手機上的 WatchKit Extension 移到 Apple Watch 中了。這將直接帶來如下改變:原來只存放一些資源和 Storyboard 的 Watch App,現在程式的業務邏輯部分(也就是程式碼執行部分)也被放到 Watch App 中。這樣的話,程式給使用者的體驗會更好,Watch App 的執行可以完全獨立於 iPhone 了。

Q3 watch os 1 & watch os 2 獲取網路資源的方法

watch os 1主要是通過WKInterfaceController的

+ (BOOL)openParentApplication:(NSDictionary *)userInfo reply:(nullable void(^)(NSDictionary * replyInfo, NSError * __nullable error)) reply WK_AVAILABLE_IOS_ONLY(8.2);    // launches containing iOS application on the phone. userInfo must be non-nil

方法交給iPhone去處理,當iPhone收到訊息後在AppDelegate中收到回撥

- (void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void (^)(NSDictionary *))reply
{}

到這裡後交給NSURLSession或者NSURLConnection處理。

watch os 2基於watch架構變化後,可以直接由watch發起網路請求,值得注意的是,Apple Watch 2 中還支援 WiFi,所以 Apple Watch 可以通過 WiFi,直接獲取一些網路資料等。並且 Apple Watch 無法處理的一些業務,可以通過 WatchConnectivity 框架的WCSession,請求 iPhone 進行處理,並將結果返回給 Apple Watch。

Q4 Apple Watch強退App的方法

雖然apple watch的應用沒有真正意義上的後臺,錶冠退出應用以後就不在執行(部分自帶應用的檢測功能不會退出)了,但下一次啟動應用會很快。可是作為一名強迫症十分想關閉後臺應用,於是發現一種關閉後臺應用的方法:如要完全退出健身應用,

第一步:進入健身應用介面

第二步:按住(長按)側邊按鈕,出現關機/省電模式介面後鬆開按鈕。

第三部:不要管介面內容,再次按住(長按)側邊按鈕,大約3秒後應用被完全退出。

如果再一次開啟這個應用可能會需要一點載入時間。

Q5 wkinterfacecontroller的生命週期

watch app是Page-Based,可以左右滑動,假設有三個interfacecontroller,剛啟動的時候,它們大概是下面這樣執行

2016-05-18 18:58:48.793 MonkeyForWatch WatchKit Extension[13295:382024] -[InterfaceController init]
2016-05-18 18:58:48.793 MonkeyForWatch WatchKit Extension[13295:382024] -[InterfaceController awakeWithContext:]
2016-05-18 18:58:48.793 MonkeyForWatch WatchKit Extension[13295:382024] -[RepositoryInterfaceController init]
2016-05-18 18:58:48.794 MonkeyForWatch WatchKit Extension[13295:382024] -[RepositoryInterfaceController awakeWithContext:]
2016-05-18 18:58:48.794 MonkeyForWatch WatchKit Extension[13295:382024] -[SettingInterfaceController init]
2016-05-18 18:58:48.794 MonkeyForWatch WatchKit Extension[13295:382024] -[SettingInterfaceController awakeWithContext:]
2016-05-18 18:58:48.794 MonkeyForWatch WatchKit Extension[13295:382024] -[InterfaceController willActivate]
2016-05-18 18:58:48.794 MonkeyForWatch WatchKit Extension[13295:382024] -[InterfaceController didAppear]
2016-05-18 18:58:49.297 MonkeyForWatch WatchKit Extension[13295:382024] -[RepositoryInterfaceController willActivate]
2016-05-18 18:58:49.298 MonkeyForWatch WatchKit Extension[13295:382024] -[RepositoryInterfaceController didDeactivate]

由InterfaceController滑動到RepositoryInterfaceController之後


2016-05-18 19:01:31.941 MonkeyForWatch WatchKit Extension[13295:382024] -[InterfaceController willDisappear]
2016-05-18 19:01:31.941 MonkeyForWatch WatchKit Extension[13295:382024] -[RepositoryInterfaceController willActivate]
2016-05-18 19:01:31.942 MonkeyForWatch WatchKit Extension[13295:382024] -[InterfaceController didDeactivate]
2016-05-18 19:01:31.942 MonkeyForWatch WatchKit Extension[13295:382024] -[RepositoryInterfaceController didAppear]
2016-05-18 19:01:32.445 MonkeyForWatch WatchKit Extension[13295:382024] -[SettingInterfaceController willActivate]
2016-05-18 19:01:37.710 MonkeyForWatch WatchKit Extension[13295:382024] -[SettingInterfaceController didDeactivate]


Q6 WKInterfaceTable如何使用

首先需要storyboard中建立表以及自定義的row,下面是初始化表檢視,SettingRow是一個NSObject物件。

- (void)initTable
{
    [self.settingTable setNumberOfRows:2 withRowType:NSStringFromClass([SettingRow class])];
    
    for (NSInteger i=0; i<2; i++) {
        SettingRow *elementRow = (SettingRow *)[self.settingTable rowControllerAtIndex:i];
        [elementRow.titleLabel setText:[NSString stringWithFormat:@"%@ 設定開發語言",@(i)]];
    }
}

table的點選事件則需要複寫WKInterfaceController的方法

- (void)table:(WKInterfaceTable *)table didSelectRowAtIndex:(NSInteger)rowIndex;  // row selection if controller has WKInterfaceTable property
{
    if (rowIndex==0) {
        [self presentControllerWithName:NSStringFromClass([LanguageListInterfaceController class]) context:nil];
    }
}
Q7 三種互動方式

Apple Watch將會有三種互動方式:主螢幕下,佩戴者可以看到所有的Watch app,使用者點選後就可以直接啟動相應app;第二種互動方式被稱做“Glance”,該介面下不含按鈕,也不可滑動,使用者只能夠進行快速閱讀,內容將只有一屏空間。開發者可以定製該介面,使用者點選後即會啟動相應app。第三種互動方式是通知提醒的定製操作。當iPhone上的通知推送至Apple Watch上顯示後,當用戶點選後就可以進入更詳細的資訊顯示頁面,開發者可以對該介面進行定製。

Q8 相容iOS6的問題

在iOS6的機器上執行,我發現了一下問題,

dyld: Library not loaded: /System/Library/Frameworks/WatchKit.framework/WatchKit
Referenced from: /var/mobile/Applications/xxxx/xxx.app/xxx
Reason: image not found
(lldb) 

因為watchkit.framework 在iOS 6上是不存在的,所以才會有上面的錯誤,這時需要在build phases裡把watchkit.framework從Required(新增framework預設為此)改為optional。

http://bbs.feng.com/read-htm-tid-9101476.html

https://developer.apple.com/library/ios/samplecode/Lister/Introduction/Intro.html