20200522のiOSに関する記事は8件です。

DribbbleでFlutterのUI実装力を高める

みなさん、こんにちは
とあるサラダ?の会社で開発やってます umatoma です。

最近はFlutterのUI実装力を高めようと、
Dribbbleで公開されているデザインをFlutterで再現してみているので、紹介したいと思います。

Dribbble

https://dribbble.com/

Dribbble is the world’s leading community for creatives to share, grow, and get hired.

Dribbbleには?のように、様々なデザインが投稿されていて、
アプリUIに関するデザインも沢山?あります。

また、動画で投稿されているものもあったりして、
アニメーションを含んだデザインが見れる点はとても良いです?

で、このDribbleで公開されているデザインをFlutterで再現して、
FlutterのUI実装力を高めようと試みています???

スクリーンショット 2020-05-22 19.49.39.png

DribbbleのデザインをFlutterで再現してみる

今の所、こんな感じでDribbbleのデザインをベースにFlutterで再現してみました。

デザイン Flutterで再現してみたやつ
Mobile Digital Wellbeing Application by Umar Abdul Azis on Dribbble sign-in-sign-up.png
Sign In/ Sign Up Page App UI by Md. Hafizur Rahaman on Dribbble
Flight and Hotel Booking App by Subash Chandra on Dribbble flight-booking.png
UI modeling. Admin mobile main views set by Maxim Aginsky on Dribbble

詳しい実装方法の説明は?で紹介しているので、良かったら見てみて下さい?

Flutterで再現してみて

形状が複雑でない多くのパーツは
標準で提供されいるWidgetを組み合わせることで簡単に実装することができました。

ですが、少し凝った形状になるとただWidgetを組み合わせるだけで
実現するのが難しくなりました?

そういった時は ClipPathCustomPaint などを使って、
自分で Path を描きデザインを実装する必要があります。

それがデメリットかと言うと、そうでもないかなと思っています。

UI modeling. Admin mobile main views set by Maxim Aginsky のインジケーター部分のように、
複雑なデザインのパーツがあたっとしても
CustomPaint などを使えば自分で描画すれば実装できてしまうという事です。

Flutterは提供されているWidgetを組み合わせるだけでも整ったUIを実装することができますが、
やはり、凝ったデザインを実装するには CustomPaint などを使いこなす必要がありそうです?

今後は、アニメーションを含めたUIの実装にチャレンジして行きたいと思います。

まとめ

  • Flutterに限らず、UI実装力を高めたい時のデザインを探すにはDribbbleを使うと良い
  • FlutterのUI実装力を高めるには CustomPaint などを扱えるようにする

最後に

今回のデザインの実装方法を含めた、
Flutter入門用のWebサイトを公開しているので、興味があったら使ってみて下さい。

Flutterで始めるアプリ開発
https://www.flutter-study.dev/

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Apple Developer Programの契約からアプリ公開まで4ヶ月かかった話

概要

個人開発でiOSアプリを製作したかったので、Apple Developer Programを契約したが、公開まで予想以上に時間がかかったので経緯を記しておく。

正直、かなり舐めていた。
契約したらその日にアプリをアップロードして審査、1週間後にはリリースぐらいに考えていた。
実際には契約してからアプリ公開まで4ヶ月を要した。

経緯

  • 01/26 Apple Developer Programを契約、$99(時価で税込¥12,980)支払い発生

  • 01/27 Apple Developer及びApp Store Connectにアクセスできるようになる

  • 01/31 20:30 App Store Connectから初めてのアプリ提出、ステータスが「Waiting For Review」になる

  • 01/31 21:30 ステータスが「In Review」になる

  • 01/31 21:40 リジェクト。メッセージは以下の通り

Hello,
We are unable to continue this app’s review because your Apple Developer Program account is currently under investigation for not following the App Store Review Guidelines’ Developer Code of Conduct.
Common practices that may lead to an investigation include, but are not limited to:
- Inaccurately describing an app or service
- Misleading app content
- Engaging in inauthentic ratings and reviews manipulation
- Providing misleading customer support responses
- Providing misleading responses in Resolution Center
- Engaging in misleading purchasing or bait-and-switch schemes
- Engaging in other dishonest or fraudulent activity within or outside of the app
During our investigation, we will not review any apps you submit. Please do not create a new developer account or make any app transfers while waiting for the investigation to be completed. Once we have completed our investigation, we will notify you via Resolution Center. Due to the nature of the investigation you will be ineligible to receive an expedited review until the investigation is completed.
We do not require any additional information from you at this time, nor do we have any additional details to share. We appreciate your continued patience during our investigation.

  • 02/01 13:40 色々調べてBundle IDを変更して別アプリとして提出、ステータスが「Waiting For Review」になる

  • 02/01 17:20 ステータスが「In Review」になる

  • 02/01 21:30 リジェクト。メッセージは上と全く同じ。

  • 02/01 21:35 アプリを微妙に修正して再度提出。ステータスが「Waiting For Review」になる

  • 02/04 10:00 ステータスが「In Review」になる

  • 02/05 3:40 リジェクト。メッセージは上と全く同じ。

  • 3ヶ月弱寝かせる

  • 05/01 さすがに待てないと問い合わせフォーム(リジェクトの意義申し立て)から問い合わせ

  • 05/16 14:00 2週間経っても返答無し。寝かせてる間に発覚したバグ等を修正して再提出。ステータスが「Waiting For Review」になる

  • 05/19 11:40 ステータスが「In Review」になる

  • 05/19 11:50 リジェクト。メッセージは以下の通り

Hello,
The review of your app is taking longer than expected. Once we have completed our review, we will notify you via Resolution Center.
If you would like to inquire about the status of this review, you may file a request via the Apple Developer Contact Us page.

  • 05/19 13:20 問い合わせフォーム(ステータスについて)から問い合わせ

  • 05/21 04:40 Appleから返信が来る、メッセージは以下の通り

This is the App Store Review team following up with you regarding your app, “APP_NAME”
I understand that you are concerned with waiting longer than you have anticipated for your app to be reviewed. However, we still need additional time. No action has been taken against your app at this time.
Once we have completed our review, we will notify you via Resolution Center of any next steps. Thank you for your patience and understanding.

  • 05/22 5:00 ステータスが「In Review」になる

  • 05/22 9:20 ステータスが「Pending Developer Release」になる(手動公開設定にしていたため)

  • 05/22 9:30 ステータスが「Processing for App Store」->「Ready for Sale」になる

結論

アカウント調査にしびれを切らしたら、問い合わせフォーム(ステータスについて)から問い合わせしよう。
公開まで長かった、、、iOSアプリは審査まで持っていくのにも色々つまずいたので本当に疲れた。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Sign in With AppleでSandboxアカウントを使う

はじめに

2020/5/22 現在の情報です
Sign in With Apple(以後、SIWA)でSandboxアカウントを使う為のメモです

SIWA自体やInAppPurchaseについての対応は割愛します。

流れ

  1. よし、SIWAの実装確認できた
  2. 課金周りテストするか、Sandboxアカウントでログインして
  3. SandboxアカウントでSIWAログインできるのかな?まぁ、やってみるか
  4. お、できた。メールにPIN送ったから入力しろって。
  5. よし、入力完了。次は?。2FA認証が必要です。設定を開いて〜
  6. 「お客様のApple IDでは、現在2ファクタ認証をご利用できません」 :thinking:

で困っていたら、Apple Developer Forumsにあったので共有と解説です


準備作業

ブラウザで作業

  1. icloud.comにアクセスして、sandboxアカウントでログイン。

  2. メールアドレスを確認する
    メールアドレスを確認する

  3. メールを確認する
    メールを確認する

  4. セキュリティ質問を入力
    セキュリティ質問を入力

  5. Apple IDとプライバシー
    Apple IDとプライバシー

  6. 利用規約に同意
    利用規約に同意


Macで作業

※ ローカルに別ユーザ作って管理した方がiCloud周りが楽です

  1. システム環境設定>Apple IDからサインイン
    Apple IDからサインイン

  2. 2ファクタ認証を有効にする
    2ファクタ認証を有効にする

  3. icloudで登録したセキュリティ質問を入力

  4. 電話番号を入力
    電話番号を入力

  5. SMSからPINを入力

  6. Macのパスワードを入力


iPhone(or シミュレータ)で作業

  1. サインイン
    サインイン

  2. 2FA認証
    2FA認証

  3. PINを入力


使う

  1. SIWAでログイン
    SIWA

  2. 課金処理[Sandbox]を呼び出す
    InAppPurchase

  3. 購入[Sandbox]完了!
    購入完了


Sign in With AppleでSandbox Accountを使うのに大事なこと

  • 受信できるメールアドレスを使ってSandboxアカウントを作成すること

参考

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ポストコロナ時代の歩き方。~密違反監視カメラ作った~

output2.gif
やぁ、やぁ、自粛解禁ムードになってきてみなさん油断していないですかね?
そんな悪い子たちのために密違反監視カメラ作りやした。
iOSのアプリで人の密を判定するアプリを作って、そのライブ映像を見れるサイトを作りました。

コンセプトは車のスピード違反取締りのオービスみたいな感じで、
人が密違反をしていたら、写真を撮ってしまうぞ!
という怖い監視カメラです。

ライブ映像はこちらから見れるますたぶん。
https://orbisforwalkers.tokyo
(5/22の午後14:00~18:00くらいの間だけ試しにライブ配信やります。それ以外は未定です。)
見れてなかったらごめんなさい、、

背景

コロナ便乗 創作欲求満たすぜ大喜利!!と言われたら反論はできない。
コロナ禍の中で、一線の研究者達が世界のために日々闘う姿をみて感動し、凡人である我々に何ができるのか考えた時に、とにかく何か作らなければと使命に駆られた....
という理由で開発したのなら格好がつくのだがそういう理由ではない。

大それたことは関係なく、何かを感じて物を作るという自然なことを日々やっていかなければならないと考えていた矢先に、コロナになったのでいつの間にかこういうプロダクトが出来てしまった。という感じだ。Gomenn...

今回のプロダクト制作の目的は大きく分けると二つで、

  • 考えた物をチームで形にしていく練習
  • 興味分野の技術習得 (技術習得のトピックは以下)
    • firebase使えるようにならんとなぁと思ってた事。(ライブ演出仕事とかインスタレーションの仕事が減るかも)
    • 最近仕事でインスタレーションの開発した際に人体検知の機械学習に触れた事 -> なにか使えるのでは?
    • 動画配信系の勉強せんとなぁと思ってた事。

これらの目的を達成したら出来てしまったという流れ.

Orbis for walkersはコロナ警察を助長するようなプロダクトであるため微妙な雰囲気はあるのだが、外出自重しろよ!!という意図ではなく、
こういうのを既存の技術で割とサクッと作れてしまうんだぞ、という事の周知としてみてもらえればと思う。また、本来の目的ぽくポストコロナ時代の歩きかたの何かしらの参考になればまぁよしと思う。
これに個人情報をくっつければ、密スコアが高い人間は逮捕といったデストピアが想像できる。「このアルゴリズムが誰かの人生を狂わせる。。」などと考えながら実装するエンジニアがこの世にはいるのだろう。
デザインはkikiがニヤリという感じにしてくれた。
180.png

システム構成

Screen Shot 2020-05-22 at 0.33.17.jpg

iOSアプリで人体検知、密スコア判定
密スコアが閾値を超えたら、画像をfirebaseに投げる。
管理画面で良く撮れた画像(個人情報特定できない画像)をパブリッシュすると、サイトに表示。
ついでに、iOSアプリで密判定を描画している様子をlive配信。
という感じのフローだ。

iOS アプリ

最近仕事で使った人体検知はwindows環境でpythonだったのだが、
アプリでサクッとみんな出来た方が楽しい説 + windows PC買う予算ない
ということでiOS環境で試すことにした。
CoreMLの勉強と思っていたが結局自作モデルは使わなかったが、
ほんと今更だけど、こんな簡単に学習モデルを用意出来てしまうとは思わなかった。時代についていけていなかった。

CreateMLでObject Detecitonの学習モデルを作りたい場合annotations.jsonをどうやって用意するか不明だったが、
IBMのCloud Annotations Toolで作れた。
Cloud Annotations Tool
annotation.jpg

こんな感じで、この画像のどの範囲にマスク野郎がいるかを決めてラベルを割り当てる作業をする。
こちらに詳しくやり方書いてあるので参考に
How to Label Data — Create ML for Object Detection | hackernoon

で、エクスポートしたデータをcreateMLに突っ込んで学習させれば、モデルデータが完成する。
コードは一行も書かない。すごい!!
ちなみに学習は数時間かかる。雑魚macだと他の作業出来なくなるので夜寝る前に開始して寝よう。

そして出来たデータは以下の公式apple developerのリンク先からダウンロードできるコードで使える。
Recognizing Objects in Live Capture

このコードを参考にfirebase周り入れてゴニョゴニョして完成。
やっぱり自作アプリが自分のiPhoneとかに入ると嬉しいね!
iphonese.png

チーム内での配信はdeploygateで行った。
どうでもよいが数年振りにiosのアプリ開発したけどまだcocoapodがスタンダードなのだろうか?firebaseの公式もcocoapodで入れるの推奨してた。

管理画面

cms.jpg
管理画面はこんな感じ。
vueでwebpack構成SPA。普通です。
フレームワークはbootstrap制のcoreUIを使いました
https://coreui.io/vue/

Firebase

firebase初心者だったので、firebaseというかfirestoreの勉強は以下の書籍で行った。
実践Firestore (技術の泉シリーズ(NextPublishing)) Kindle版
RDBに少し慣れてるとfirestoreでのデータ構造やコレクションの設計どうするかとか謎だったが、

この本読んで色々すっきりしました。mysqlとかいじったことある人がfirestoreなんぞ?の時はこれがベストな気がする。
あとちょっと古いけどmonoさんの記事とか。
Cloud Firestoreの勘所 パート1 — 概要
皆様ありがとうございました。


現場

iPad proを三脚に固定するマウント。
mount.jpg

ipad防御するカバー。
Otterbox defenderのiPad pro12.9用。重くてデカイしかも高い1万円以上する。普通は絶対買わない。
otterbox.jpg

こんな感じで撮影する予定
IMG_1115.JPG

5/22(金)の午後は街を撮影しながらlive配信しようかと思っている。
どうぞよろしく。


  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【swift】singleton(シングルトン)とその代替案について

はじめに

今回は、シングルトンについて書いていこうと思います!
シングルトンとはなんぞやと言うところから、シングルトンを使う場面やメリットについて公式ドキュメントを元に書いていきます!

公式doc:Managing a Shared Resource Using a Singleton

共有リソースの管理者:シングルトン

公式ドキュメントのタイトルにある通り、シングルトンは共有リソースにアクセスします。
ざっくり言えば、インスタンス内の値を変更後、別のインスタンスを生成しても前者のインスタンスの更新内容が反映されるどういった処理が可能になります。

つまり、インスタンスが1個しか生成されないことを保証します。

イメージとしては、こちらの記事がとても参考になるので一読をお勧めします!
シングルトンについて swift

まず、コードでみていきます!

class single {
    var name = "singletonのお勉強"
    static let singleton = single()  //staticキーワードでsingle()をsingletonに代入
    private init(){}
}

var test = single.singleton  //最初のインスタンス
print(test.name)  //出力:singletonのお勉強
test.name = "singleton実装"

let singleton = single.singleton  //値更新後のインスタンス
print(singleton.name)  //出力:singleton実装

見ての通り、static let singleton = single() の部分でsingletonを作ります。
そうすることで、複数のスレッドで同時アクセスされた場合でも、1回だけ遅延して初期化されることが保証されます。

また、初期化以外の設定を実行する必要がある場合は、以下のようにクロージャーを用いることもあります。

class singleton{
  static let sharedInstance: singleton = {
    let instance = singleton()
    //追加設定処理
    return instance
   }()
}

シングルトンの使う場面

この機能についてはおおよそわかったが、では一体どのような場面でシングルトンを使うのだろうか、、

Swift におけるシングルトン・staticメソッドとの付き合い方

こちらの記事によると、

  • delegateにシングルトンインスタンスしか渡せない場合
  • インスタンスメソッド実装が必要な既存のプロトコルに準拠させたい場合
  • その他、大体の場合staticプロパティ・メソッドを束ねたstructで代用できる

え、singleton使う場面、めっちゃ少ないやん

この記事の筆者曰く、swiftの場合、singletonの実装が簡単なので必要なくても使ってもいいのではと。

シングルトンは大抵、staticプロパティ・メソッドを束ねたstructで代用できる

実際にコードで見ていきます


struct MyStruct{
  private init(){}
  static var value = "original"
  static func foo() { print("foo") }
}

var myStruct = MyStruct.self
myStruct.foo()

myStruct.value = "シングルトンもどき"
print(myStruct.value)  // シングルトンもどき
print(MyStruct.value)  // シングルトンもどき

確かに、、シングルトンと同じだ、、

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

iPhoneからの転送時のエラー

iPhoneとPC(Windows)をUSB接続し、写真や動画などをコピーする際に、
「システムに接続されたデバイスが機能していません」/「A device attached to the system is not functioning(英語OSの場合)」
というエラーが出る場合は、

iPhone側で、設定-写真-「MACまたはPCに転送」項目で、「自動」を「元のフォーマットのまま」に変更してみる

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Flutter で Firebase Crashlytics を使おうとすると ネットワークエラーが発生する問題

結構ハマったので共有します。

概要

FlutterでFirebaseのCrashlyticsを使おうと、手順通りに設定していったのに、下記のエラーがでて疎通できない問題についてです。

[Fabric] failed to download settings Error Domain=FABNetworkError Code=-5 "(null)" UserInfo={status_code=403, type=2, request_id=, content_type=application/json; charset=utf-8}

Crashlyticsの画面も疎通待ちのまま更新されません。。。
Screen Shot 2020-05-22 at 7.28.07.png

やったこと

まずは、FlutterとFirebase自体を接続します。
1. Firebase consoleでプロジェクトを作成し、iOS向けのアプリ追加ウィザードを進めます。
2. 途中で GoogleService-Info.plist をDLできるのでXcodeのRunner/Runnerに設置します。(このファイルがiOSとFirebaseの接続情報となります)
3. ウィザードの最後に接続待ちとなるので、Flutterをビルドすると接続が完了となります。

次に、Firebase Crashlyticsの接続をします。
1. Firebase consoleでCrashlyticsを開いてSDK追加し疎通待ちの状態にします。
2. https://pub.dev/packages/firebase_crashlytics のiOS Integrationに従って設定します。
3. Flutterをビルドすると疎通が完了するハズです。が、疎通できません。。。

海外サイト等を調べてみると以下のような解決アプローチは載っていましたが、すべて該当しませんでした。。。

  • pubspec.yaml のロード順を変更する
    firebase_coreよりも後にfirebase_crashlyticsを書くこと
  • XcodeのInfo.plistに手書きでAPI Keyを追加する(旧式のやりかた?)
  • XcodeのRunScriptのInput Filesに以下を追加(Xcode 10のみ) \$(BUILT_PRODUCTS_DIR)/$(INFOPLIST_PATH)

解決策

半ばあきらめつつも調べていると、1つのIssueを見つけました。
https://github.com/FirebaseExtended/flutterfire/issues/1592
同じようなアプローチだなぁと思いつつ、最後の方を見てみると「実機でテストするとうまくいきました」と書いてある!

もしやと思いつつさっそく、実機でテストしたところ疎通できました!
Crashlyticsの画面も疎通完了しました!
Screen Shot 2020-05-22 at 7.39.35.png

解決できてよかったです。
その後、クラッシュデータを送信してみたのですが、これもシミュレーターからはうまく届かず、実機からであればデータが届き、Firebase Crashlyticsでも確認できました。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【SwiftUI】基本的なモディファイアの種類と使い方①

bodyプロパティ

定義:var body: Self.Body
ContentViewではカスタムビューの内容を記述する
複数のViewを組み合わせるにはVStackなどを使用してひとつにまとめる必要がある。

frameモディファイア

フレームのサイズとビューの配置位置を指定

func frame(width: ,height: , alignment: ,)
alignmentの種類
center,leading,trailing,top,bottom,topLeading,topTrailing,bottomLeading,bottomTrailing
func frame(minWidth: ,idealWidth: ,maxWidth..)

cssでいうwidth,height,

fixedSizeモディファイア

ビューの表示を固定

func fixedSize() -> some View
func fixedSize(horizontal:Bool,vertical:Bool) -> some View
horizontal 横方向のはみ出しを許すか
vertical 縦方向のはみ出しを許すか

borderモディファイア

境界線を表示

func border(content:境界線のスタイル ,width:線の太さ )
contentにはColor,ImagePaint,LinearGradient,RadialGradientなどが入る

cssでいうborder

positionモディファイア

ビューの中心を親の座標空間の指定された座標に配置

func position(x: .y: ) -> some View

positionを指定するとそれまでのframeの設定がリセットされる、フレームサイズは強制的に親ビューと同じになる。フレームサイズを指定してその中に座標系を作りたい時はpositionの後にframeモディファイアを指定。
cssでいうtop,bottom,left,right

offsetモディファイア

元の位置を基準としてビューの表示位置をずらす

func offset(x:横方向へずらす距離, y:縦方向にずらす距離)

cssでいうmargin

edgesIgnoringSafeAreaモディファイア

指定された辺に対して、ビューの配置可能領域をセーフエリアの外へ拡張

func edgeIgnoringSafeArea(_ edges: Edge.Set) -> some View
引数edgesの種類top,bottom,leading,trailing,horizontal,vertical,all

.edgesIgnoringSafeArea(.vertical)

paddingモディファイア

ビューの周りの余白を追加
cssと同じ

func padding(_ length: CGFloat) -> some View
引数にはtop,leading,bottom,trailingを指定できる

.padding(.init(top:10,bottom:30,trailing:50))

backgroundモディファイア

背景設定

.background(Image("aaa_image"))
.background(Color.yellow)

cssと同じ

foregroundColorモディファイア

ビューの前景要素に使う色を設定
テキストビューの場合文字色の指定
cssのcolorと同じ?

.foregroundColor(Color.yellow)

overlayモディファイア

ビューの前に別のビューを重ねて配置
重ねるビューのサイズは元のビューサイズに制限される
画像にキャプションを付けることも可能

Image("logo-image")
    .overlay(
     Text("hello")
     font(.largeTitle)
     .foregroundColor(.white)
     .padding(),
     alignment: .top)

*要素のサイズがフレームに収まりきらないときに切り捨てられるのはテキストビュー特有の動作

clippedモディファイア

ビューをフレームの境界で切り取る
定義func clipped(animated: Bool) -> some View

Image("aaa_image")
    .frame(width:100,height:100)
    .clipped()

clipShapeモディファイア

ビューの切り取り形状を指定
シェイプの種類
Capsule-カプセル状
Circle-円
Ellipse-楕円
Path-任意のパス
Rectangle-四角形
RoundedRectangle-角丸四角形

Image("aaa_image")
    .clipShape(Circle())

maskモディファイア

引数のビューを使ってマスクする

Image("haikei_image")
    .mask(Image("temae_image"))
ビューを透過させることも出来る
.mask(Color(red:0.0,blue:0.0,green:0.0,opacity:0.5))

cornerRadiusモディファイア

指定されたコーナーの半径でビューを角丸にクリップ
cssのborder-radiusと同じ

Image("aaa_image")
    .cornerRadius(10)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む