1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【IT-DIY】AppleWatchを使って、インターネット回線を必要としないチャットツールの作成(Part.2)

Last updated at Posted at 2022-12-28

※こちらの記事はPart2です。
 Part1はこちら↓
 https://qiita.com/nextvision-sugakir/private/d2c9222160284639a156

はじめまして、IT企業に入社して1年目のSEです。
Part1では開発までの道のり、DIYするアプリの概要までをご紹介しました。(Step1~Step3)
Part2では、DIYの実施から完成品の試用までをまとめました。

【Step4】いざ実装

まず仕様をおさらいすると、iPhoneからAppleWatchにメッセージを送信する。AppleWatchはメインのアプリ画面を更新し、画面の上部に新規のメッセージを表示する。
今回作る機能は以下の通りです。

  • ボタン、ラベルの実装(AppleWatch側アプリ)
  • メッセージの入力機能(iPhone側アプリ)
  • データの送受信の機能(両者の疎通確認)

となります。それぞれ書籍等を参考に実装してみます。

まずはiOSのアプリからAppleWatchのアプリに接続したいと思います。既にOS側が提供してくれているWatchConnectivityライブラリをViewControllerにインポートするだけで接続が確立します。

//Connect,AppleWatch
import WatchConnectivity

//Add WCSessionDelegate
class ViewController:UIViewController,WCSessionDelegate{

    func session(_ session:WCSession, activationDidCompleteWith activatationState: WCSessionActivationState, error:Error?){
        
    }
    
    func sessionDidBecomeInactive(_ session:WCSession){
        
    }
    
    func sessionDidDeactivate(_ session:WCSession){
        
    }
    

ボタン、ラベルの実装
XcodeにおけるUIの実装はとても簡単です。iPhoneとAppleWatchに共通しているのですが、配置したいコントロールを選択してドラッグアンドドロップするだけです。あとはプロパティでちょちょいと細かい設定をするだけです。
image.png

メッセージの入力機能
メッセージはiPhone側のテキストボックスを用いて送信します。先ほどのUIの実装の要領で、テキストボックスをiPhone側に配置し、ViewControllerでそのテキストボックスにデータの送受信処理を記述します。

データの送受信の機能
iPhoneからメッセージを送るメソッドは以下のように設定しました。ボタンを押下、すなわちメッセージを送信後に、次の入力に向けてテキストボックスを初期化しています。

    //Describe send message
    
    @IBOutlet weak var messageBox: UITextField!
    @IBAction func sendButton(_ sender: Any) {

        
        //Set message
        if (messageBox.text == ""){
            return
        }
        let message = ["send" :messageBox.text]
        
        //Send Apple Watch
        WCSession.default.sendMessage(message as [String : Any], replyHandler: {reply in print(reply)}, errorHandler: {error in print(error.localizedDescription)})
        messageBox.text = ""
    }
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        
        //Start to Session WatchConnectivity
        if (WCSession.isSupported()) {
            let session = WCSession.default
            session.delegate = self
            session.activate()
        }
        
        messageBox.text = ""
    }

受信側のAppleWatchはInterfaceControllerに以下のように設定しました。

    //Receive data
    func session(_ session: WCSession, didReceiveMessage message: [String : Any], replyHandler: @escaping ([String : Any]) -> Void) {
        
        addCount += 1
        let index = 0
        tableDataList.insert(message["send"] as! String, at: 0)
        table.insertRows(at: [index], withRowType: "Row")
        table.setNumberOfRows(tableDataList.count, withRowType: "Row")
        tableDataList.enumerated().forEach{index, value in
            let row = table.rowController(at: index) as! TableRowController
            row.configure(.init(index: index, text: value))
            row.delegate = self
        }
        replyHandler(["watch" : "OK"])
    }

【Step5】DIY中に気づいた最後の壁

今回のDIYはiPhoneで送信したメッセージをAppleWatchは通知で受け取ろうとしていました。しかし、DIYを始めてからAppleWatchのとある仕様に気づきました。
それは、AppleWatchの通知(Notification)は、iPhoneがスリープ状態の時のみ通知されるというものでした。
私は根本的なことを見落としていたのです。そもそもAppleWatchはあくまでもiPhoneの拡張機能であり、iPhoneがスリープ状態の時、すなわち携帯を見ていないときに知らせる、という仕様は至極当然のことでした。
しかし今回のDIYでは、ビジネスシーンでの利用を考慮して、iPhoneとAppleWatchの使用者を分ける(以下の図を参照)という発想で進めたかったので、ここで大きな課題となったのです。
image.png

【Step6】気づいた問題に対する対策

私はここでも諦めませんでした。今回の表題のアプリは、オフラインで使える、といった仕様です。オフラインで利用するためには、通知の実装を避けなければなりません。まずは今回のDIYで通知を実装出来ないとなった際のデメリットをあげてみました。

  • 即時に気づけない

ぱっと思いつくのは、意外にもこれだけでした。とはいっても即時に気づけないのはとても大きな課題です。次に私はこの課題の改善策を考えました。即時に気づけないと具体的に何が困るか、またそれに対する対策をあげていきます。

1. 緊急性の高いメッセージにすぐに対応できない
2. アプリ画面を開いて、常に目視で確認しなければならない
これらの問題を改善するために、以下のような機能を実装しました。メイン画面に新しいメッセージが表示されるタイミングで、バイブレーションを起動します。

// vibration
WKInterfaceDevice.current().play(WKHapticType.notification)

わざわざ通知画面を表示しなくとも、バイブレーションによって気づくことが出来るので、これらの課題はクリアです。

3. メッセージを見落としたまま次のメッセージが送られてきた際に、確認漏れが発生する
最後に3つ目の課題については、ログの機能によって対策しました。

extension InterfaceController: TableRowControllerDeligate {
    func tableRowController(_ tableRowController: TableRowController, didTapDeleteButtonAt index: Int){
        tableDataList.remove(at: index)
        table.removeRows(at: [index])
        tableDataList.enumerated().forEach{ index, value in
            let row = table.rowController(at: index) as! TableRowController
            row.configure(.init(index: index, text: value))
            row.delegate = self
        }
    }
}
protocol TableRowControllerDeligate: AnyObject {
    func tableRowController(_ tableRowController: TableRowController, didTapDeleteButtonAt index: Int)    
}
final class TableRowController: NSObject {    
    struct Config {
        let index: Int
        let text: String
    }    
    weak var delegate: TableRowControllerDeligate?
    private var index: Int = 0
    @IBOutlet weak var label: WKInterfaceLabel!    
    func configure(_ config: Config){
        label.setText(config.text)
        index = config.index
    }  
    @IBAction func buttonAction() {
        delegate?.tableRowController(self, didTapDeleteButtonAt: index)
    }
}

image.png
次々とメッセージが送られてくる場合、逆に通知画面では確認しきれないこともありますし、今回の目的は「携帯を開かなくてもよい」というものなので、通知では把握しきれず、過去のメッセージを見るためにわざわざアプリを開くのは、AppleWatchのメリットを活かせていません。ならば最初からログとしてメイン画面の上部に新しいメッセージを追加することで常に最新の3件は確認することが可能です。(DigitalCrownを回すことでさらに確認できる)

【Step7】デザインを整える

まず、DIYにより完成したアプリがこちら
image.png
うーん、iPhoneの画面をもっとアプリっぽくしたい!
ということで背景色等をイジって。。。
image.png
それっぽいのが出来ました!

デザインに関しては、用途や使用する人に合わせて簡単に変更できます。これもXcodeのデザインの拡張性の強さですよね。

これらのDIYにより実現できたAppleWatchのDIYを次のStepでシミュレータにて試用してみたいと思います。

【Step8】完成品を使ってみた(内部シミュレータ)

最後に、完成したアプリを動かしてみたいと思います!
まずは、シミュレータで両方のアプリを起動します。今回の仮想端末は、iPhone12とAppleWatch Series7です。
操作手順を順を追って説明していきます。

➀テキストボックスにメッセージを入力して「Send request」ボタンを押す
5807097b-f708-4eec-8a02-07e519de292d.jpg

➁AppleWatch側のトップにメッセージが表示される
3fd2b7dc-5f21-4382-a414-4e711c24ca28.jpg

➂AppleWatch側の✕ボタンを押すと
0cc2aba5-59a5-44d7-a63b-24c9f16f41e9.jpg

➃選択したメッセージが削除されます。
5d1f3815-c326-4a4e-a7e1-65a354710bcd.jpg

まとめ

今回は、アプリの構想を練るところから製造、テストまでをご紹介しました。AppleWatchをはじめとしたウェアラブルデバイスは、市場では最近よく見かけるようになったものの、ビジネスシーンではコスト面のこともあり、まだあまり見かけません。しかし、AppleWatchのバイブレーション機能のように、ウェアラブルデバイスは、人間と一体になることで効果を発揮する機能があふれています。この観点で考えると、働き方改革に直結するシステムとかも生み出せそうですね。
今回作ったアプリも、これで終わりにするのではなく、地道に改良を重ねてより良いものにしていきたいと思います!(面白い発見があれば、Part3以降で取り上げるかもです。。。)

いかがだったでしょうか?今後も本取り組みを続けていこうと思うので、実機テストが出来た、あるいはアプリに進展があった際は、都度展開しようと思います。
最後までお読みいただきありがとうございました!
ではさようなら~

おまけ

なぜ配信して実機でテストしないの?
今回のアプリは弊社のMacで作成しました。実機でテストするとなると、私のAppleWatchをMacに接続しなければなりません。業界のルール的に、個人のデバイスを会社のデバイスに接続するのは、セキュリティ面でよくないですよね。。。なので今回は内部のシミュレータ止まりとなったのです。
あ、ちなみに、TestFlight等でアプリを配信して実機テストする際も、配信時にAppleWatchのUUIDを登録しなければいけないので、似たような取り組みをされる方は注意が必要ですね!
もっとも、私がMacを持っていれば話は別なんですけどね。。。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?