文系iOSエンジニアの備忘録

エンジニア iOS Swift

運行、渋滞予測、天気(API)についてのサービス調査

はじめに

今回現場で使いそうな運行、渋滞予測、天気、について提供しているサービスを調べました。 ほとんどNavitimeでまかなえそう。

比較

運行  :電車の遅延情報に基づいた経路検索を出したい

渋滞予測:渋滞情報に基づいた経路検索を出したい*


RailGo

利用は有料で、経路検索メソッドへの月間アクセス数に応じて課金となる。

価格の詳細:

利用料金:月間アクセス数 10,000単位 月額10,500円(税込)〜1,000,000単位 月額315,000円(税込) ※1ヵ月の体験使用が可能

  • メリット ・遅延情報や渋滞情報の提供と情報に基づいた経路の提供などがある。

  • デメリット ・沖縄の運行情報について強いかわからない


・mixway API

公共交通はもちろん徒歩、自動車、シェアサイクル、ィなどを組み合わせたマルチモーダルなナビゲーションを提供している。

2019年7月から提供されていて、最近できたサービス。

  • メリット

バス、電車、船、タクシーなどを考慮した経路検索や運賃計算、遅延や混雑時の迂回経路をまとめて利用できる。

  • デメリット

Google MAPや標準のMAPUIと相性が良くない可能性がある。 混雑情報や遅延情報などはこちら側では使用できず、それらの情報を元にした迂回経路の情報しか提供されていない。 天気予測:天気に情報に基づいた経路検索を出したい


・Weather2020 API

Rakuten RapidAPIのAPIドキュメント サービスプロバイダーのWebサイトのドキュメント:Weather2020ドキュメント 価格の詳細:Weather2020 APIの価格の詳細

  • メリット

企業や消費者向けに正確で長期的な予測を作成できます 1Weatherなどのいくつかの一般的なモバイルアプリケーションで既に使用されています、さらに、1日に1,000万件以上の予測を提供します 主要な気象指標、傾向、および重要な更新を含むインタラクティブダッシュボードと分析を提供します

  • デメリット 有料の顧客のみが利用できるビデオ予測

ViewBuilderの仕様。※VStackには10個までしか置いちゃいけません

本買ったのさ

会社の誕生日プレゼントでSwiftUIの本買ってもらいました。 これ→SwiftUI徹底入門

レビュー見た通り、一通りiOS開発したことある人向けでした。 既存の基本的なUIKit,Founationの使い方、ライフサイクルとか知ってる前提。

ViewBuilderの仕様

SwiftUIではVStack,HStackのようなスタックレイアウトを利用しますが、10個までしかViewを並べられないと。(10個も並べるほどやってはないけど)

引数にSwift5.1からのファンクションビルダを利用したViewBuilderを渡すんですが、中身見たらbuildBlockに10個までのViewを受け取るメソッドが定義されてるんですよ。

つまりbuildBlock(a:View),buildBlock(a:View, b:View)...みたいな。 なんで10個までなのかも気になるけど意外だった。

※そのあとみたらGroupとかを使ってうまく10個以内にしたりするらしいですね〜。

CoreMotion実装ナレッジ

どうもおはようございます、こんにちは、こんばんは。

はじめに

ユーザーが今なんの交通手段を利用しているか把握するための実装でデフォルトのCoreMotionではどこまでできるかの確認。

動作状態の取得

iOSはCoreMotionというフレームワークを使うことで、加速度センサーやや端末の動作状態(歩き、自転車、自動車)、歩数の取得を行うことができる。

実際に走ってみたががっつり走らないとRunにはならなかった。 ネットの情報を見ると精度を上げれば結構リアルタイムに検知してくれるそう。

位置情報を取得している間は時間が青くなる。

動作状態の取得実装

CMMotionActivityManagerインスタンスを作成し、センサーを使用して良いか許諾をとる。 状態の取得、DBに送信。

private var activityManager = CMMotionActivityManager()

private func  gethogehogeMotion() { // 
    self.activityManager.startActivityUpdates(to: OperationQueue.current!,
            withHandler: {(data: CMMotionActivity?) in
            DispatchQueue.main.async(execute: { () in
                guard let exData = data else {
                    return
                }
                let stationary = exData.stationary
                let walking = exData.walking
                let running = exData.running
                let automotive = exData.automotive
                let cycling = exData.cycling
                switch exData.confidence {
                case .low:
                    self.confidenceLabel.text = "Low"
                case .medium:
                    self.confidenceLabel.text = "Medium"
                case .high:
                    self.confidenceLabel.text = "High"
                @unknown default:
                    fatalError("not confidence")
                }
                if stationary {
                    self.status = "stationary"
                } else if walking {
                    self.status = "walking"
                } else if running {
                    self.status = "running"
                }
                if automotive {
                    self.status = "automotive"
                } else if cycling {
                    self.status = "cycling"
                }
                self.activityStateLabel.text = self.status
                self.firestore.db.collection("activity").addDocument(data: ["state":self.status])
            })
        })
    }

最後に

やっぱ機械学習とかが必要になってきますよね。 というか他の行動把握の外部サービスも取得しているデータは基本一緒でどう活かすか、ロジックに組み込むかって気がす。

SilentLogってサービス利用(デモ版使用するにも打ち合わせあったりめんどい)や 以下のようなサイトも参考になりました。 http://www.vled.or.jp/odpc-archive/

 

ブログの投稿は基本毎日19時頃する予定です。

ダークモード時でもアプリでライトモードを適用する方法

どうもおはようございます、こんにちは、こんばんは。  

はじめに

実際に入っていた案件で、ダークモードを使用するとTableViewなどでデフォルトを利用し色指定していないUIは黒くなったりします。

それを防いで、どちらでも統一したUIにするために対応しました。

アプリ全体に適用するには

Info.plistのUIUserInterfaceStyleパラメータをLightにします。

これで常にライトモードになります。

簡単!

なおAutomatic(自動)Dark(ダークモード)を指定することもできます。

なお設定しない場合や不正な値が入力された場合は常にLightが採用されます〜。

 

ブログの投稿は基本毎日19時頃する予定です。

位置情報関連ナレッジ(CoreLocation、Firestore)

どうもおはようございます、こんにちは、こんばんは。

ちるたろうです。

 

 

はじめに

アプリで位置情報を取得する際に気になること(バックグラウンドでの取得や充電の消費など)について調査しました!

検証用アプリ作成でバックグラウンドで取得して、FirebaseFirestore(DB)に保存、後に取得とかをやってみたのでまとめます。

バックグラウンドでの取得

バックグラウンドで必要な実装は大きく分けて3つ。

OSの位置情報取得ダイアログを出す。

現在地の取得処理。

取得した現在地を保存、今回の場合はFirebaseのDBに保存。

位置情報の取得タイミング

意図的に取得をストップさせる、もしくはアプリのタスクをキルした場合は取得がされません。

それ以外は、フォアグラウンド、バックグラウンド共に動作することを確認しました。

バイスがスリープ状態でも位置情報をDBに送信していたことからスリープ時でも取得可能です。

位置情報の取得に関する設定

位置情報の取得は

  • 取得距離間隔
  • 取得時間間隔(Timerなどで)
  • 取得アクティブタイプ(歩きの場合だけ、動いていない時は送信しないなど)

などの設定ができる。(ただし、必ずしもその間隔で動くとは限らない。) ※設定できるプロパティ全て確認したわけではないので他に利用可能なものがあるかもしれない。

消費電力

位置情報精度をkCLLocationAccuracyBestForNavigationとkCLLocationAccuracyBestでそれぞれ設定して確認した。

取得間隔は毎秒。 使用端末はiPhone11, iOS13。

kCLLocationAccuracyBestForNavigationは約30分で5%。 kCLLocationAccuracyBestは約30分で2%。

実装方法

前提環境

  • Googleアカウントを作成する
  • Firebaseでプロジェクトを作成する。

https://firebase.google.com/docs/firestore/quickstart?authuser=2#swift 公式サイトに載ってますが簡単な流れを一応。

FirebaseFirestoreをインストールする

Podファイルに

pod 'Firebase/Firestore'

記述して

$ pod install 実行。

Cloud Firestore を初期化する

AppdelegateのdidFinishLaunchingWithOptions内で

FirebaseApp.configure() let db = Firestore.firestore() 初期化。

位置情報取得実装

1. iOSの位置情報取得ダイアログを出す。

まず、CLLocationManagerを初期化して設定をする。

private var locationManager: CLLocationManager!
locationManager = CLLocationManager()
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.distanceFilter = 5
locationManager.allowsBackgroundLocationUpdates = true

上記のallowsBackgroundLocationUpdatesをtrueにすることでバックグラウンドでの取得を可能にする。

次に、位置情報取得ダイアログの取得処理を追加する。 locationManager.requestWhenInUseAuthorization()

これで位置情報取得許可のダイアログが表示され、許可をすれば位置情報の取得が可能になる。

2. 現在地の取得

まず、許可されているかを確認し、位置情報の取得を開始する。

let status = CLLocationManager.authorizationStatus()
if status == .authorizedWhenInUse || status == .authorizedAlways {
  locationManager.delegate = self
  locationManager.startUpdatingLocation()
}

次に、CLLocationManagerDelegateを実装する。

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {}

が位置情報が変更されるたびに呼ばれるのでこの中で現在地を取得。

3. 取得した現在地を保存、Firestoreに保存

didUpdateLocations()のlocationsから最新の緯度経度を取得する。

let location = locations.last
let latitude = location?.coordinate.latitude
let longitude = location?.coordinate.longitude

addDocument()でFirestoreに登録する。

詳しい実装については公式ドキュメントを参照。

let myLocation = firestore.db.collection("locations")
        let name = UIDevice.current.name
        let data: [String: Any] = [
                            "name":name,
                            "createAt":FieldValue.serverTimestamp(),
                            "latitude":self.latitude,
                            "longitude":self.longitude]
        myLocation.addDocument(data: data) { (err) in
            ¥if let error = err {
                print("error:\(error)")
           } else {
                print("saved!")
         }
}

 

ブログの投稿は基本毎日19時頃する予定です。

コメントや反応もらえると嬉しいです!よろしくお願いいたします!

現場で使ったSwiftで書けるOSS一覧

どうもおはようございます、こんにちは、こんばんは。

ちるたろうです。

 

 

はじめに

以前、案件で使ったライブラリ一覧です。 基本MITライセンスのもの。

Moya,Kingfisher,R.swiftとかは最初から使用検討していましたが それ以外はsprintを進めるごとに出てきた要件に合わせて追加してきました。 現場の方がまとめていただいたのをこちらに備忘録として再度まとめました。

Moya

  • https://github.com/Moya/Moya
  • Star 33.3k
  • 鉄板ネットワーク通信ライブラリ「Alamofire」のラッパー。APIManagerなどNetworkレイヤーのモデルクラスをアプリ開発者はいちいちつくる手間がなくなる。 API呼び出しのインターフェースをMoyaに統一することができる。SwiftらしくProtocol-Oriented に書かれてるのが良き。

Kingfisher

R.swift

  • https://github.com/mac-cain13/R.swift
  • Star 7.3k
  • リソースファイル呼び出し(画像やフォント、Storyboard IDなど)を「強い型付け」できるライブラリ。リソースを文字列として呼び出すとtypoなどリスクがあるが、それを防ぐことができる。 R.swiftなしだと UIImage(named: "settings-icon") と書くところを、 R.swift導入すると、 R.image.settingsIcon() と書くことができる。

SideMenu

導入時のアプリでは、各タブに導入している。左上の「三」ボタンからスライドメニューが表示される。

SwiftGif

PullUpController

DeviceKit

 

ブログの投稿は基本毎日19時頃する予定です。

コメントや反応もらえると嬉しいです!よろしくお願いいたします!

SwiftでQRコード実装する場合(駅での仕様を想定)

どうもおはようございます、こんにちは、こんばんは。

ちるたろうです。

QRコード実装

はじめに

SwiftにはCore Image という標準で提供されているAPIを利用してQRコードを作成することができます。 QRコード作成、読み取りに関するOSSなどもいくつかありました。 今回は、一番標準的な実装で検証しました。

実装内容

@IBoutlet var QRImageView: UIIMageView! 
let text = "https://XXXX.com" // 今回は文字列でURL取得を想定。
guard let data = text.data(using: .utf8) else { return nil }
guard let QR = CIFilter(name: "CIQRCodeGenerator", parameters: ["inputMessage": data]) else { return nil }
let transform = CGAffineTransform(scaleX: 10, y: 10)
guard let ciImage = QR.outputImage?.transformed(by: transform) else { return nil }
guard let cgImage = CIContext().createCGImage(ciImage, from: ciImage.extent) else { return nil }
QRImageView.image = UIImage(cgImage: cgImage) 

可用性はOS X v10.9以降とiOS 7.0以降で利用できるので問題なし。

・表示例

f:id:chiltarou1224:20200727005146p:plain

参考: CIFilter 公式ドキュメント

QRコード実装に必要な情報

どんな文字列情報が必要なのか。

  • 人数
  • 読み取り期間
  • 区間(一日乗車券だから必要ない?)
  • 乗車可能かの判定? など。

おそらく改札で使用する場合は、入場中かその乗車券が有効期間か、など状態はサーバが持つことになる。

考えうる障害

テストをどのようにするか

検証機のようなものがあるのか?

読み取り機にQRをうまく認識されるかのようなテストケースも実際に開発段階でどこまで対応できるか。

ネットワークエラーでQRコードが端末上にうまく表示できない場合などは出来そう。

セキュリティ面

コピー対策やスクショ対策など。 例えば切符を購入した場合、1枚のQRコード切符を複数人でコピーして利用される。

→ こちらは、海外の例でいうと改札通過時は当該のQRコードが有効かどうかのみをチェックし、出場時に必要な条件を満たしているのかを確認する。この場合、有効かどうかはIDの確認だけで良い。

  切符の1枚1枚にユニークIDを埋め込んでおけば、最初の1枚が改札を通過した瞬間にそのIDでの入場は無効となり、コピーを使っての複数人乗車はできなくなる。

  乗車中、あるいは物理的に離れた場所にあるところで短時間に利用が確認された場合、後から利用されたものをロックする。

他の決済手段との競合

Suica」と違いアプリの場合は1日乗車券が購入できるようにしたいが、どのくらい上記のICカード利用者がアプリを通じて利用するか不明。

通勤の場合は、ポイント付与や割引もあるのであまり利用されないのではないか。

ApplePayを入れるとマネタイズの観点からおいしくない。

複数人乗車の場合

どのようなやり方があるのかは未検討。

参考:https://www.watch.impress.co.jp/docs/series/suzukij/1232490.html

 

ブログの投稿は基本毎日19時頃する予定です。

コメントや反応もらえると嬉しいです!よろしくお願いいたします!

【2020年版】AppStoreへの公開手順(ArchiveからAppStoreCponnectで公開)

はじめに

iOSって証明書や設定しなければならない部分が結構あって 慣れてしまえばただの作業なんですが、年々UI変わったりツールも変わったりするので

現在のipaファイル作成〜AppStoreConnectでの公開までをまとめました。(2020年3月時点)

参考サイトも載せますが、現在と若干違う部分があるので、 2020年で自分の場合こんな感じっていう例でスクショ入れつつ面倒かった部分を載せていきます。

自分なりに調べてやりましたが、分かりにくいところがあるかもしれません。

いろいろコメントなどで教えていただければ幸いです。

手順

1. Appleアカウント作成、Apple Developer Programに登録

 iOSアプリ公開やPush通知するためには、有料アカウントにする必要があります。

 税込み1万3000円くらい。

 企業用アカウントでは申請できないので個人アカウント作成で。  登録して承認されるまで2日くらいかかるらしいんですが、自分は電話したら速攻承認してくれました。

 すぐやりたい方は電話とか問い合わせしてみては。

2. Certificate作成

 証明書です。どのDevelopperですかみたいなやつ。

 作り方に関しては探せば出てきます。

 若干記事と違うのはXcode11以降からはApple Distributionを選択すること。

 昔のやつはiOS Distribution (App Store and Ad Hoc)っすね。

 申請というかArchiveするにはDistribution用が必要です。

 開発する際はDevで。

こんな感じ。

f:id:chiltarou1224:20200726201633p:plain

 

3. AppID作成、Provisioningfile作成

すでに開発してあればあるはずですが一応。  

AppIDはIdentiferタブから作成です。

 詳細は省きますが画像だけ。

  f:id:chiltarou1224:20200726201639p:plain

追加されるとNameの横に本当は決めたbundleIDが表示されてます。

f:id:chiltarou1224:20200726201642p:plain

ProvisioningfileはProfileタブから。

こちらも詳細は省きます。

申請の場合はAppStoreを選択です。

f:id:chiltarou1224:20200726201646p:plain
自分の場合は1アプリに対してDev,Adhoc,AppStore用を作成。

EnterPrise版ははそれ用のアカウントで。

f:id:chiltarou1224:20200726201651p:plain


4. Device追加(必要な場合)

AddHocで配信する場合にここで登録した端末でしかインストールできないので使いたい場合は追加します。

TestFlight使う人とかAdhoc配信しかしてない現場とかはやります。

登録上限もあって一年に一回しか削除できない(厳密にいうといつでも削除はできるがゴミ箱にいる状態)ので気を付ける必要もあります。

EnterPriseでDeploygate配信するとかなら端末制限ないので気にせずとも。

5. AppStoreConnectにアプリ登録

調べると出てくるので省きまっす。 バンドルIDとか洗濯して名前登録するやーつ。

6. App情報編集

名前、サブタイトル、プライバシーポリシーURL、カテゴリを設定して、「保存」。

プライバシーポリシーは今年くらいから必須になりましたので注意。

プライバシーポリシー作成はGithubにhtmlファイル置いてやるやり方が主流だと思いますが

自分はApp Privacy Policy Generator というサイトでやってます。 余裕があれば詳しく書きます。

f:id:chiltarou1224:20200726201655p:plain


7. バージョン情報編集

バージョン情報の編集は主にAppStoreで公開されたアプリページに載せる画像や説明文などを追加します。

画像は縦か横を選択できますが、トレンド的には横です。(横の方がインストール率が高い。)

枚数は、3枚からあまりインストール率に関して大差ないデータがありました。 なので特になければ3枚あれば十分かも。

ツールはPixel Materを使いました。 Appアイコンとかデザインはこれでやりました。

AdobePhotoShopまではいらない人とかにおすすめです。ここら辺は自分で好きなのを。

f:id:chiltarou1224:20200726201704p:plainf:id:chiltarou1224:20200726201712p:plainf:id:chiltarou1224:20200726201721p:plain


8. アーカイブ作成&アップロード

こちらは今度詳しく書きます。 「ipa作成」,「xcode archive」とかで検索すれば出ていきます。

アップロードはXcodeそのままやるか、Transporter使って上げるかです。 昔はApplicationLoaderとかでした。

9. アプリを審査提出、公開

先ほどのバージョン情報を編集するところでアップロードしたアプリを選択して、審査提出をします。

公開のタイミングは3種類あります。 1. 審査が通った瞬間自動で 2. 審査認可後、手動で好きなタイミングで。 3. 審査認可後、予約したタイミングで出す。

です。

リジェクトされなければ1〜2日で許可でした。 ネットとかだと2~3日が多いですが、昔に比べるとかなり早くなってきてるようです。

最後に

長いし見辛いところもあると思いますが、 気になる部分だけ参考にしていただければと思います。 雑な部分はあとで別記事とかに書ければ書きます。

手探りしながらの申請だったので、もちろん

「私、俺ならこうやるよ」

っていうのがあればご教示いただければ幸いですm(._.)m

参考サイト: 【2019年版】iOSアプリをApp Storeに公開するための全手順まとめ 個人開発者がAppStore用にプライバシーポリシーを書く

Xcode PreViews 〜FlutterのHot reloadみたいな!〜

どうもおはようございます、こんにちは、こんばんは。

ちるたろうです。

 ## はじめに

UI実装ナレッジ、今回はXcode Previewsです。

Xcode Previews

Xcode PreviewsXcode上でコードを変更した際、リアルタイムにPreviewを表示するための機能で、

SwiftUI とともに導入されたXcode11の新機能のひとつです。

Xcode Previewsは、SwiftUIで利用されているものだと思っていましたが、

UIKitのUIViewやUIViewControllerといった従来のView実装もPreviewできるようです。

参考:Mastering Xcode Previews - WWDC 2019 - Videos - Apple Developer

実装方法

1.Xcode Previews 専用のターゲットを作る プレビューさせる画面に関連するソースコードとプレビュー用の swift ファイルを対象にして、

iOS13 以降をターゲットバージョンとする

f:id:chiltarou1224:20200726195218p:plain

2.対象のクラスを UIViewRepresentable に準拠させる updateUIView メソッド内で施した変更がプレビューに即時反映される

f:id:chiltarou1224:20200726195225p:plain

3. PreviewProvider に準拠させた struct を定義 static var previews: some View でプレビューに必要な処理を施す

f:id:chiltarou1224:20200726195308p:plain

参考:SwiftUI Tutroial

メリット

  • コードでUI実装が簡単に記述できる。
  • シミュレータ や実機のビルドをしなくてもコードの変更が即時反映される。(FlutterのHot reloadのような)

デメリット(注意点)

  • 開発環境がまだ限定的。 (iOS13以上、Xcode11、MacOS Chatalina以上)
  • まだ、AutoLayoutの代替とは言い難い。(機能的に足りない部分)    凝ったデザインの作り方やベターな実装方法が確率されていないような。

最後に

まだやりたいことが全部できていないんですが、少し進んだかなと🤏 SwiftUIでの実装も進めてますが、blurとか円形切り取りとかの画像加工だったり UIパーツの配置はすごく簡単でイイ感じですね。

 

ブログの投稿は基本毎日19時頃する予定です。

コメントや反応もらえると嬉しいです!よろしくお願いいたします!

UI実装ナレッジ〜AutoLayoutのPreview〜

どうもおはようございます、こんにちは、こんばんは。

 ## はじめに

UI実装ナレッジの共有です。

Preview機能とは

StoryboardやXibファイルを実装中の複数端末レイアウトを一度に確認できる機能です。 ビルドの必要はなく、すぐに反映されます。

機能的には割と昔から提供されていたようですが、

Xcode11になってからアシスタントエディタ(名前知らなかったけど右上のタブ)の仕様が変わったので導線が変わりました。

使ってみる

1.Storyboardファイルを選択肢右上の「三」をタップ。

f:id:chiltarou1224:20200726191916p:plain

2. 出てきたpreviewの左下の+ボタンを押下して確認したいデバイスを選択する。

f:id:chiltarou1224:20200726191921p:plain

3. 制約や文字内容を変更すると即時反映される。  あえてiPhone SEでボタンが見切れるようにしています。

f:id:chiltarou1224:20200726191929p:plain

最後に

可変的なデータを使用する場合では、やはり実際にシミュレータ や実機で動かしながら確認というのも必要ですが、

Preview を使った確認で大きなレイアウト崩れや、他端末を考慮した出戻りなどが幾分か減ると思います。

 

ブログの投稿は基本毎日19時頃する予定です。

コメントや反応もらえると嬉しいです!よろしくお願いいたします!