Help us understand the problem. What is going on with this article?

ウィジェットでBitbankの自分の資産を確認できるようにした

More than 1 year has passed since last update.

なぜ作ろうと思ったか

仮想通貨大好きな友だちから「ウィジェットで各通貨の値段は確認できるけど資産を確認できないのは不便」という声が。
ランチ1回で買収されて作ってみた。

↓は既存のビットバンクのウィジェット
スクリーンショット 2018-05-25 15.45.27.png
確かに各コインの値段はわかるけど自分の資産情報はない

作ったもの

アプリ側で表示したいコインとBitbankのPrivateApiを叩くためのApiKey、ApiSecretを保存

IMG_2679.PNG

それをウィジェットで表示するもの

スクリーンショット 2018-05-25 15.48.37.png

1つのコインの資産を見たいとリクエストされたので今回は1つのコインの総資産、現在の価格を表示

Today Extension

iOSではこのウィジェットのことをToday Extensionと呼ぶ。
ターゲットの追加や実装方法などは他の方もあげているので一旦スルー
自分が詰まったところ中心に書きます。

ウィジェットのサイズを大きくするには

よくある表示を減らす、表示を増やすを押したら広がるもの。

TodayViewController.swift
    override func viewDidLoad() {
        super.viewDidLoad()
        self.extensionContext?.widgetLargestAvailableDisplayMode = NCWidgetDisplayMode.expanded
    }

widgetLargestAvailableDisplayModeを設定して表示を増やせるようにし、

TodayViewController.swift
    func widgetActiveDisplayModeDidChange(_ activeDisplayMode: NCWidgetDisplayMode, withMaximumSize maxSize: CGSize){
        if (activeDisplayMode == NCWidgetDisplayMode.compact) {
            self.preferredContentSize = maxSize;
        }
        else {
            self.preferredContentSize = CGSize(width: 0, height: 100);
        }
    }

このように増やした際の高さを指定。

どのタイミングでAPIを叩けばいいのか

TodayViewController.swift
    func widgetPerformUpdate(completionHandler: (@escaping (NCUpdateResult) -> Void)) {
        completionHandler(NCUpdateResult.newData)
    }

ウィジェットが表示されるたびにwidgetPerformUpdateが呼ばれる。(viewDidAppearてきな感じ。。?)
ここでAPI叩いた結果に対してNCUpdateResultに値を渡してあげる。

NCUpdateResultNewData - 内容が入れ替わったのでビューの再描画が必要
NCUpdateResultNoData - 更新は不要
NCUpdateResultFailed - 更新処理中にエラーが発生

UserDefaultsをアプリ間で共有

今回はアプリ側でコインとAPIの情報をUserDefaultsに保存。それをToday Extension側で読み込んでAPIを叩く必要があった。

TargetのCapabilitiesを選択
新しいApp Groupsを作成し、両方のTargetにそのApp Groupsを設定

スクリーンショット_2018-05-25_17_13_53.png

このApp GroupsでUserDefaultsのインスタンスを作成し、保存、読み込めばデータが共有される。

let defaults = UserDefaults(suiteName: "group.共通のID")

リリースする際などはApple DeveloperからApp Groupsを作成して〜〜などしないといけないので注意

PrivateAPIを叩くためのHMAC-SHA256署名

個人的に今回一番詰まった。。
BitbankのProvateAPIを叩くには 「UNIXTIME、リクエストのパス、クエリパラメータ」 を連結させたものをAPI Secretと使ってHMAC-SHA256で署名しなくてはならない。

今回は以下のライブラリを使用

CryptoSwift

cocoapodsでインストール

pod 'CryptoSwift'

以下のように署名して使用

    private func makeAccessSignWith(accessKey: String, unixtime: String, path: String, queryParam: String) -> String? {
        let unixTimeStr = self.makeHaederUnixTime(unixTime: unixtime)
        let linkedStr = unixTimeStr + path + queryParam

        var bytes: [UInt8] = []

        bytes += linkedStr.bytes

        let signedString = try? HMAC(key: "APISecret", variant: .sha256).authenticate(bytes)

        return signedString?.toHexString()
    }

しかし叩けど認証エラーが返ってくる。。。
署名の作成方法が間違ってるのかと思っていると意外なとこで原因判明
BitBankのAPIドキュメントのページで自分のAPIキーとAPIシークレットを入力すると実際にAPIを叩いて確認することができるのだけれどそこのUNIXTIMEが
be0c74b4-c5a4-4b58-9bb7-db85ecb1ba0f.png

なぜ100年前。。。
この変なUNIXTIMEで一度APIを叩いたことが原因でその後も認証エラーがでてたよう。
クライアントから叩く際にUNIXTIMEに1000掛けして解決

今後

いまは一個のコインしか表示してないので全部表示して資産も全部足した資産にしよう

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away