↑クリックして拡大
↑クリックして拡大
↑クリックして拡大
↑クリックして拡大

頭痛が減ったので共有です!

rebuild.fmを応援しています!

HOME > App Extensions #4

App Extensions #4(Today)

前回の記事Shareを説明していましたが、今回はTodayの実装方法を解説してみます。AppExtensionのShareでdidSelectPostの箇所のソース、上記のエラーが解決できない箇所まで進んでいました。


参考:Pro tip: Build a Today iOS 8 app extension using Xcode 6

まずは作成してみます。

Shareと同じように、New->TargetからAppExtensionのTodayを選択します。

todayサンプル0

todayサンプル1

プロジェクトに[Today]フォルダが生成されます

todayサンプル1

shareフォルダの中には、以下3つのファイルが含まれています

TodayViewController.swiftの中身はこんな感じです。見慣れないNCWidgetProvidingwidgetPerformUpdateWithCompletionHandlerが 追加されています。このあたりでイベントを取得設定できると思われます。


import UIKit
import NotificationCenter

class TodayViewController: UIViewController, NCWidgetProviding {
        
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view from its nib.
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    func widgetPerformUpdateWithCompletionHandler(completionHandler: ((NCUpdateResult) -> Void)!) {
        // Perform any setup necessary in order to update the view.

        // If an error is encountered, use NCUpdateResult.Failed
        // If there's no update required, use NCUpdateResult.NoData
        // If there's an update, use NCUpdateResult.NewData

        completionHandler(NCUpdateResult.NewData)
    }
    
}

completionHandlerで取得できるNCUpdateResultには以下の3つのパターンがあります。

参考:NCWidgetProviding

さて、プログラム側のイベントの取得はわかりましたが、どうやってビュー繋がるのかがイマイチわかりませんので、調査を続けます。

MainInterface.storyboardの中身は以下のような感じになっています。

todayサンプル3

ひとまず、サンプルを見本にプログラムからビューへ表示するコードを実行してみる

View部分とつなげる為に、IBOutletを登録します。


 import UIKit
import NotificationCenter

class TodayViewController: UIViewController, NCWidgetProviding {
    
    //IBOutletでnameLabelを追加する
    @IBOutlet weak var nameLabel: UILabel?

    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
    
    func widgetPerformUpdateWithCompletionHandler(completionHandler: ((NCUpdateResult) -> Void)!) {
        //追加したnameLabelに文字をセットする
        self.nameLabel?.text = "swift-salaryman";
        completionHandler(NCUpdateResult.NewData)
    }
}

上記IBOutletを追加した状態だとStoryBoardのOutletにnameLabelが追加されますので、以下のようにnameLabelHelloWorldを関連づけてあげます。

todayサンプル4

この状態で実行すると、下のようにswift-salarymanが表示されました!

todayサンプル5

※わかりずらいですが、swift-salarymanの上に表示されている[today]が追加時に登録したToday拡張の名前になりますので可変です。

ウェジェットが表示されたタイミングで、viewDidLoadが実行されるようですので、メインのアプリで保存しているデータ等をNSUserDefault等で連携させて表示を切り替えることができれば 様々なことができそうです。コンパイルしても動作しない等のまだまだ不具合も多い新規の機能のようですので今後に期待しつつ、、、

検証(画像は追加できるのか)

読み込み部分で以下画像を追加して実行してみます。


    override func viewDidLoad() {
        
        let url = NSURL(string:"http://swift-salaryman.com/files/icon_1.gif");
        var err: NSError?;
        var imageData :NSData = NSData(contentsOfURL:url!,options: NSDataReadingOptions.DataReadingMappedIfSafe, error: &err)!;
        var img = UIImage(data:imageData);
        
        let iv:UIImageView = UIImageView(image:img);
        iv.frame = CGRectMake(0, 0, 100, 50);
        self.view.addSubview(iv);
        
        super.viewDidLoad()
    }

できました!

todayサンプル6

おまけ

Info.plist の Bundle display nameを変更すると、Widgetの名前を変更できるようです。(2014/12/17)

todayサンプル7

おまけ#2 画面左のスペースを削除する方法

todayサンプル7

デフォルトではTodayの画面左にはマージンスペースが20pxほど追加されていますが、以下の関数をTodayViewControllerに追加することで回避することができます。


    func widgetMarginInsetsForProposedMarginInsets(defaultMarginInsets: UIEdgeInsets) -> UIEdgeInsets {
        return UIEdgeInsetsZero;
    }

todayサンプル9

おまけ#3 Todayガジェットからホストアプリを立ち上げる場合

TodayガジェットからはUIApplicationのopenURLが使えないのですがextensionContextからホストアプリを起動することが可能です。以下の例は TodayガジェットからdemoAppアプリ(ホスト)を起動しています。


        self.extensionContext?.openURL(NSURL(fileURLWithPath:"demoApp://")!, completionHandler: nil)
        

さて、どうやってNSURLのURLスキームdemoAppを設定しているのでしょうか?ホストプロジェクトのTarget -> Info -> URL Types -> +(追加) -> URLスキームの入力を追加することで関連づけます。

todayサンプル10

続きをApp Extension #5に追加しました。次は[Actions]を説明しています。よかったらご確認下さい(2015/1/7)

↓こんな記事もありますよ!


2021-05-14 14:21:41

WatchOSのwatchconnectivityのFiletransferの落とし穴。と、避け方。

AppleWatch 実機だと成功するんだけど、シュミレーターだと失敗するという、、、 昔作成してた時は成功してたのになーと思って調べると、どうやら昔は成功してたみたい。watchOS6以降は...

2021-05-06 14:04:37

LINEのアニメーションスタンプ制作の落とし穴、、、失敗談

ゴールデンウィークにLINEスタンプを作成してみました。 作り切って申請も通したんですが、意図したアニメーションと違う、、、、 LINEクリエーターの画面だと、アニメーションのプレビュー...

2021-05-01 18:05:35

久しぶりのAdmobをobjective-cに実装。コンパイルエラーだらけ。バーミッション不具合でエミュレータにインスコできない。

忘れないようにメモ エミュレータにアプリをインストールする際にパーミッション系のエラーがでた時、また、iphone実機にインストールする際にも権限系のエラーが出る場合。 ターゲット→ex...
このエントリーをはてなブックマークに追加
右側のFacebookのLikeをクリック頂けると記事更新の際に通知されますので宜しければご利用下さい!