- 1. SwiftでType Eraserを使い、genericなAPI protocolを作成する
- 2. Massive View Controllerの真実
- 3. iOS 13時代の Locale (言語と地域)基本おさらい【重要】
- 4. Flutterウィークリー #81
- 5. 「iPhone 設定をアプリから操作してらくらく環境構築」のQRコードの内容の解析編
- 6. 【実践編: 内側の2つの円】iOSでVIPERとClean Architecture 円の内側から作る
- 7. 【iOS13】scene(_:willConnectTo:options:)のオプションとセッションの NSUserActivity の違いについて
- 8. FlutterでHello worldを動かすまでの環境構築手順(iOS, Android)
- 9. NativeScriptを用いたVue.jsモバイルアプリ開発の環境構築
- 10. [iOS13] Settings.bundleのグループ名が重複すると設定アプリの内容が正しく設定されない
- 11. [iOS13] 既存アプリのiOS13対応でハマったこと(現在進行形)
- 12. SwiftUIでTextViewを使う
- 13. Firebaseを紐付けたGoogleAnalyticsのプロパティやアカウントの変更はFirebase上からしようとするとデータが消える
- 14. ズンドコキヨシ with Combine
- 15. 【コードでAutoLayout】関連付けた2つのUIViewのtranslatesAutoresizingMaskIntoConstraintsがtrueとfalseの組み合わせの場合の挙動
- 16. Apple Storeから警告?が来た Missing Push Notification Entitlement の対処方
- 17. UIButtonのフォントサイズを横幅に合わせて調整してくれる設定
- 18. Operation (NSOperation) 実装方法
- 19. Pythonistaで指紋認証
- 20. (多分)いちばんシンプルなUIScrollViewの実装
SwiftでType Eraserを使い、genericなAPI protocolを作成する
## I. はじめに
APIをViewControllerなどに持たせる場合、直接APIを持たせるのではなく、modelを取得するインターフェースを持つprotocolを作成し、それに準拠した実態としてのAPIをDIすると言うやり方で実装する人が多いのではないだろうか。
protocolをgenericにしてAPIのレスポンスの型を差し込み使いまわしたいところだが、protocolをgenericにしてしまうと、それを変数として宣言できなくなってしまうため、毎回個別にprotocolを定義しなければいけない。
今回はこの問題をType Eraserと言うテクニックを使い、genericだが変数として保持可能なprotocolを作成することで解決したと思う。
## II. よくある実装例
### protocolを作成
ユーザーを取得するインターフェースをprotocolとして作成“`UsersRequestable.swift
protocol UsersRequestable {
func fetch(completion: ((Result<[User
Massive View Controllerの真実
Massive View Controller。おそらこの言葉を聞いたことがある人は、それに悩まされたことがある人かもしれない。Massive View ControllerとはView Controllerに処理が集中して一つのView Controllerの膨大の量のコードが書かれてしまったもののことを言う。
View ControllerがMassiveになってしまうと
– コードの見通しが悪い
– コードを変更しにくい
– テストがしにくい
– etc.などなど様々な弊害が発生する。もっと色々あると思うが、それはMassive View Controllerと対峙してきた各々の心の中にとどめておいてもらおう。ではなぜView ControllerはMassiveになってしまうのか?その原因を探り、View Controllerのダイエット方法の見つける参考にしたい。
## MVCは実はMとVだけ
Massive View ControllerはMVCのアーキテクチャで生まれることが多い。それはMVCではViewControllerが事実上のVie
iOS 13時代の Locale (言語と地域)基本おさらい【重要】
#### Locale (ロケール)とは「言語 Language」+「地域 Region」
**en-JP** (英語 + 日本地域)
これを Locale identifier (ロケール識別子・アイデンティファイア)と呼ぶ。
「言語」+「地域」が基本形だが例外もある。「地域」が無い場合や「字体」「方言」が付く場合など。
Locale が決まると『小数点 decimal separator』『ケタ区切り文字 grouping separator』『通貨記号 currency symbol』などが自動的に決まる。
**なにを基準にして決まっているか?** → 「世界の実情に合わせて決まる」。
「言語」だけで決まるわけでも「地域」だけで決まるわけでもない。
例:
[スペイン語] + [スペイン地域] = 小数点はカンマ ,
[スペイン語] + [アメリカ地域] = 小数点はピリオド .[日本語] + [スペイン地域] = 小数点はピリオド .
[日本語] + [アメリカ地域] = 小数点はピリオド .おおまかな印象では、英語では「地域」を根拠に、英語以外では「言
Flutterウィークリー #81
# Flutterウィークリーとは?
FlutterファンによるFlutterファンのためのニュースレター
https://flutterweekly.net/この記事は#81の日本語訳です
https://mailchi.mp/flutterweekly/flutter-weekly-81※Google翻訳を使って自動翻訳を行っています。翻訳に問題がある箇所を発見しましたら編集リクエストを送っていただければ幸いです。
# 読み物&チュートリアル
### 複数の画面とそれらの操作方法
https://blog.codemagic.io/flutter-tutorial-multiple-screens-and-how-to-navigate-them/
Flutterアプリの画面内をナビゲートする方法に関するScott Stollのチュートリアル。### Googleマップを使用したFlutterクラスター
「iPhone 設定をアプリから操作してらくらく環境構築」のQRコードの内容の解析編
この記事は iOSDC 2019 LT の「[iPhone 設定をアプリから操作してらくらく環境構築](https://speakerdeck.com/orgachem/easy-provisioning-iphone-using-configuration-profile-via-ios-app)」の補足です。
# 背景
iOS 11 から Wi-Fi を QR コードで設定できるようになって便利ですよね。ただ、事情があって iOS 11 へあげられない方もいると思います。その方向けに iOS 11 未満でも使える Wi-Fi 設定ライブラリ [WiFiQRCodeKit](https://github.com/Kuniwak/WiFiQRCodeKit) を作成してみました。その過程はちょっと面倒でした。
# ちょっと面倒の詳細
## QR コードの読み取りまず、標準ライブラリで QR コードを読み取れるようになるのは iOS 11 からです。
iOS では QR コードの読み取りライブラリが豊富です。そのため、ここでは苦労しませんでした。今回は [yannick
【実践編: 内側の2つの円】iOSでVIPERとClean Architecture 円の内側から作る
[前回の記事](https://qiita.com/EnVacance/items/785ad911731840e38b07)の続きのVIPER Clean Architectureの実践編である。
この記事では内側の2つの円の部分まで作成する。今回カバーする部分はとても簡単なのでほとんどの人が問題なく読み進められると思う。
今回作るのは以下の図解の **真ん中の2つの円、EntitiesとUse Cases** の部分だ。これを円の内側から順番に作っていく。
![CleanArchitecture.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103299/15baba5c-d8ec-3d91-3114-d54f52a4ee4a.jpeg)
[The Clean Architecture by Robert C. Martin (Uncle Bob)](https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-archi
【iOS13】scene(_:willConnectTo:options:)のオプションとセッションの NSUserActivity の違いについて
【iOS13】scene(_:willConnectTo:options:)のオプションとセッションの NSUserActivity の違いについて
## はじめに
`scene(_:willConnectTo:options:)`での`NSUserActivity`からのシーンの復元処理について、多くのAppleのテンプレートでは以下のようになっています。“`Swift
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
if let userActivity = connectionOptions.userActivities.first ?? session.stateRestorationActivity {
// UIの復元処理を行う
}
}
“`
この時に、`session`または`connectio
FlutterでHello worldを動かすまでの環境構築手順(iOS, Android)
# FlutterでHello worldを動かす
仕事でFlutterを扱うことになったので、とりあえずHello world動かすところまでの流れをメモ。「Flutterとは何ぞや?」って人は公式サイトを見てくれ。
[Flutter – Beautiful native apps in record time ](https://flutter.dev/)## 環境
Flutter SDKは、Windows、macOS、Linux向けに提供されていますが、本記事ではmacOS上での環境構築手順をまとめます。| OS | バージョン |
|:-:|:-:|
| macOS | Mojave バージョン10.14.6 |Flutter SDKは「v1.9.1+hotfix.4」を使いました。
※バージョンアップ等で本記事の情報が古くなっている場合は、公式ドキュメントを参照してください## Flutter SDKのインストール
まずはFlutter SDKをインストールします。
[macOS install – Flutter](https://flutter.de
NativeScriptを用いたVue.jsモバイルアプリ開発の環境構築
# 概要
NativeScriptを用いてVue.jsモバイルアプリを作る際の環境構築の手順をまとめました.– NativeScript・・・本物のモバイルネイティブアプリをJavaScriptで開発するためのオープンソースフレームワーク
– NativeScript-Vue・・・Vue.jsを使ってモバイルアプリを作成するためのNativeScriptのプラグイン# 環境
– Mac OS X 10.14.6
– Node.js v12.12.0
– NativeScript 6.1.2
– NativeScript-Vue 2.4.0# 手順
## NativeScriptのシステム要件のセットアップする
下記ページに従い,macOSでNativeScriptアプリをビルドして実行するために必要なすべてのシステム要件をセットアップします.
最後の手順で`tns doctor`コマンドを実行して問題が検出されなければ次のページに進む前に本記事に戻り,次の手順に進んでください.[NativeScript Advanced Setup — macOS – Native
S
[iOS13] Settings.bundleのグループ名が重複すると設定アプリの内容が正しく設定されない
業務内容なのでスクショはテストアプリを作って後々更新します。
iOS13検証をする中で、アプリのSettings.bundleのRoot.plistに
「同じ名前のグループ」
があると、インストール後設定アプリに内容が正しく反映されないことがわかりました。
回避方法はグループ名をユニークにするだけですが、チェックがめんどくさいので
スクリプトを書きました。“`sh
xmllint –xpath “/plist/dict//string[text()=’PSGroupSpecifier’]/following-sibling::key[text()=’Title’]/following-sibling::string” Root.plist | sed ‘s/\/string>/\/string>\’$’\n/g’|uniq -c | awk ‘{if($1 > 1){print $0}}’
“`XMLLintさんで「PSGroupSpecifier」のあるアイテムの「Title」の「String」を引っ張ってきて、改行してuniqをかけます。1 以上の行があったら出力し
[iOS13] 既存アプリのiOS13対応でハマったこと(現在進行形)
# 既存アプリのiOS13対応。楽勝かと思ったらアンドキュメントな罠が。。。
現在進行形な既存アプリのiOS13対応で、アンドキュメントな変更によりはまったところを、同じ状況な人のために残しておきます。## CoreBluetooth Peripheralの取れるタイミング
今までは、“`objective_c:objective-c
_centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
“`
の後に、“`objective_c:objective-c
[_centralManager retrievePeripheralsWithIdentifiers:identifiers];
“`
で取れたんですが、(いや、実際には、取れるとは限らないんですが)
iOS13になってからは、**ちゃんと**“`
– (void)centralManagerDidUpdateState:(CBCentralManager *)central;
“`
のイベントが通ってか
SwiftUIでTextViewを使う
SwiftUIではUIKitのUITextViewに対応する物がありません。
TextFieldには[LineLimit](https://developer.apple.com/documentation/swiftui/textfield/3277098-linelimit)なるプロパティーも存在して複数業の入力ができそうですが、
2019年10月現在では、SwiftUIでT複数行入力できるViewを使うにはUITextViewをラップするしかなさそうです。ここら辺も普通のUIViewRepresentableのお作法ですが、
“` .swift
struct TextView: UIViewRepresentable {
@Binding var text: Stringfunc makeCoordinator() -> Coordinator {
Coordinator(self)
}func makeUIView(context: Context) -> UITextView {
let text
Firebaseを紐付けたGoogleAnalyticsのプロパティやアカウントの変更はFirebase上からしようとするとデータが消える
## はじめに
このお話はフィクションだったらよかったんですが実際に起きてしまった悲しい出来事です。
これ以上同じ轍を踏むアプリ開発者が出ないことを祈ってこの記事を書きました。FirebaseAnalyticsをGoogleAnalyticsに連携させたけど連携先のアカウント間違ったのでFirebase上で一旦連携をオフにして正しいアカウントに紐付けてみたらAnalyticsデータがすべて吹っ飛びんだ阿呆とは私のことです。
— masaibar@「のぞきみ」リリース (@masaibar) October 24, 2019
ズンドコキヨシ with Combine
### TL; DR * 3年前に流行ったツイートと[RxSwiftを使った記事](https://qiita.com/bricklife/items/4bf8c0e17043498f4452)を思い出したのでCombineで再現してみました
ズンドコキヨシをCombineで再現してしまった...
— mshrwtnb (@mshrwtnb_) October 25, 2019
* 元ネタはこちら
【コードでAutoLayout】関連付けた2つのUIViewのtranslatesAutoresizingMaskIntoConstraintsがtrueとfalseの組み合わせの場合の挙動
AutoLayoutを始めたのが最近なので3周遅れぐらいでいろいろ調べている。暖かく見守っていただきたい。
2つのViewに関連をつけるときにtranslatesAutoresizingMaskIntoConstraintsの設定が片方だけtrueのときの挙動はどうなるか。#前提
ソースで書く。Storyboardは使わない。#UIViewとUIViewの組み合わせ
viewA : AutoLayoutがオフ
viewB : AutoLayoutがオン
とする。viewAが何かの方法でframeが確定したとき、関連付けられているviewBは意図する設定がされるのか?####結論
viewAもAnchorの値は有効。
viewAのAnchorが決定するので、関連付けられたviewBのAnchorを決定することができる。####コード
```
//testView1.translatesAutoresizingMaskIntoConstraints = false
testView1.frame = CGRect(x: 30.0, y: 50.0, width: 50
Apple Storeから警告?が来た Missing Push Notification Entitlement の対処方
#はじめに
xcodeのバージョンは11
[ionic](https://ionicframework.com/jp/docs/intro)で開発したアプリです。#アーカイブ作成+アップロード後に起きた
[【2019年版】iOSアプリをApp Storeに公開するための全手順まとめ](https://qiita.com/kenny_J_7/items/92378e2a09bee6080677)
上記のページでの**手順8**の後にApp Store Connectからメールが来た。。
>Dear Developer,
>We identified one or more issues with a recent delivery for your app, >"アプリ名" 1.0 (1). Your delivery was successful, but you may wish to >correct the following issues in your next delivery:
>ITMS-90078: Missing Push Notification E
UIButtonのフォントサイズを横幅に合わせて調整してくれる設定
コードから
```swift
let button = UIButton()
button.titleLabel?.adjustsFontSizeToFitWidth = true
button.titleLabel?.minimumScaleFactor = 0.3 // 30%まで小さくなる
```Stroryboardから設定出来るようにするextention
```swift
@IBDesignable
extension UIButton {
@IBInspectable var adjustsFontSizeToFitWidth: Bool {
get { return titleLabel?.adjustsFontSizeToFitWidth ?? false }
set { titleLabel?.adjustsFontSizeToFitWidth = newValue }
}
@IBInspectable var minimumScaleFactor: CGFloat {
get { re
Operation (NSOperation) 実装方法
Operationの実装方法には2種類あり、どちらのタイプも並列で処理されます。
|タイプ|概要|
|:---|:----|
|**non-concurrent** タイプ| 同期的なタスクをOperatioon化する|
|**concurrent** タイプ| 非同期的なタスクをOperation化する|# non-concurrentタイプ
画像の合成など同期的な処理をOperation化したい場合は、`non-concurrent` タイプを実装します。
以下のメソッドをオーバーライドします。
* `main()`
実装例
```swift
class RequestOperation: Operation {
func main() {
//同期的なタスクを実装すること
self.createImage()
//main関数終了後自動的にqueueから削除される
}
}
```**mainメソッド終了後、OperationQueueから削除される**
したがって非同期的な処理が実装できないため、
Pythonistaで指紋認証
# 概要
Pythonistaで指紋認証をしただけ
# コード
```python:touch_id.py# coding: utf-8
from objc_util import *
import threadingNSBundle = ObjCClass('NSBundle')
LocalAuthentication = NSBundle.bundleWithPath_(
'/System/Library/Frameworks/LocalAuthentication.framework')
LocalAuthentication.load()
LAContext = ObjCClass('LAContext')class AuthFailedException(Exception):
passclass AuthCancelledException(AuthFailedException):
passclass AuthTimeoutException(AuthFailedException):
passclass AuthNotAvailable
(多分)いちばんシンプルなUIScrollViewの実装
# UIScrollView入門
UIScrollViewの一番シンプルな実装方法を書きます。
※Swift5, Xcode11.0で説明いたします。## UIScrollViewを配置し、制約をつける
![Q1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208118/1da5041d-64eb-ebde-c611-b979da0a2103.gif)- UIScrollViewを配置
- UIScrollViewに対して、サイズと配置を決める制約を設定
(サンプルでは画面いっぱいに表示されるようにしてます)画面の一部をスクロールビューにしたい場合は、この段階で制約をつけておきます。
## スクロールさせるViewを配置し、制約をつける
![Q2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208118/f2044c88-a6f4-87b7-88f7-0e38138c734c.gif)- U