- 1. DateFormatterの和暦バグの解決法を考える
- 2. 【XcodeCloud】XcodeCloudで実行した時はBuildPhasesのRunScriptを実行したくない
- 3. iOS17 + XCode15 + Swift + OpenCV
- 4. 【Swift】配列から特定要素を削除
- 5. UIKitとSwiftUIのViewの描画周りで気をつけること
- 6. Coordinatorクラスについて簡単にアウトプット
- 7. UIViewRepresentableプロトコルについて簡単にアウトプット
- 8. モバイル端末の発熱情報をUnreal Engine上で取得する
- 9. 【SwiftUI】バッジの見た目を変更する
- 10. iOS17以降から使えるObservationについて
- 11. モバイルアプリのアクセシビリティ対応(スクリーンリーダー、VoiceOver)
- 12. Web Share API で、canvasに描画した画像と、指定したハッシュタグをTwitterの投稿にコピーペーストする
- 13. 【SwiftUI】ScreenTimeAPIで特定のアプリを一定時間全く使用できないよう制限する
- 14. 【Swift】特定の要素の次の要素、前の要素を取得する
- 15. 非日本語圏日本語フォント問題、SwiftUIにおける対処事例(2023年中旬)
- 16. 古いバージョンのXcodeをインストールする方法
- 17. SwiftUI ProgressViewのカスタマイズでできること・できないこと
- 18. [iOS] Firebase Authenticationで匿名認証してからAppleIDと紐付ける方法
- 19. Flutterってどうなん?実際に商用アプリ開発で使ってみた感想
- 20. 【SwiftUI】PhotosPicker使ってみた
DateFormatterの和暦バグの解決法を考える
# はじめに
DateFormatterとは、SwiftでDate型の日付を文字列に変換するときに使用するオブジェクトです。
実はこのDateFormatter、使い方を誤ると**思わぬバグを生み出してしまいます**。
※ 現在時刻は`2023/9/30 12:34`だとして説明します。
“`swift
let date = Date() // 現在時刻
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = “yyyy/M/d HH:mm”
let r = dateFormatter.string(from: date)
print(r) // 2023/9/30 12:34
“`
上記のコード、一見問題なさそうに見えますよね……?
しかし、実行する端末の設定によっては、`0005/9/30 12:34`と表示されてしまうバグを含んでいるのです。 「設定」アプリを開いて「一般>言語と地域>暦法」を「和暦」に設定した端末でこのコードを実行すると、そのバグを観測できます。
暦法の設定
【XcodeCloud】XcodeCloudで実行した時はBuildPhasesのRunScriptを実行したくない
# はじめに
SwiftLintをRunScriptでビルドしてたのですが、XcodeCloudでの実行時間がめっちゃ長くなっちゃうので、
XcodeCloudで実行された時は処理をスキップしたいことがありました。
その時にRunScript上でXcodeCloudで実行されていることを検知する環境変数を知ったので記事にしておきます。# 実装
“`sh
if [ “$CI_XCODE_CLOUD” == “TRUE” ]; then
echo “✅ XcodeCloudで実行されました”
else
echo “❌ XcodeCloud以外で実行されました”
fi
“`これを使ってXcodeCloudの時は処理をスキップしたい時はこうなります。
“`sh
if [ “$CI_XCODE_CLOUD” == “TRUE” ]; then
exit 0
fi# 行いたい処理
“`# おわり
XcodeCloudの実行時間が15分 → 3分に短縮されました!# ドキュメント
https://developer.apple.com/documenta
iOS17 + XCode15 + Swift + OpenCV
iphone15も出たし、iOSでOpenCVを使いたいと思い調査したところ、Objective-C関連は何もしなくても良くなってるみたい。Podもあるから楽勝!と思いきや、エラーがでて使えなかったので、コツコツとMakeしたら動くようになったのでメモしておきます。
# 試した環境
Macbook Air M1
Xcode15
MacOS Ventura 13.5.2# 事前準備
Cmakeをインストールbrew install cmakePython3をインストール
brew install python3# OpenCVのMake
Gitから落としてくるgit clone https://github.com/opencv/opencv.git -b 4.6.0 git clone https://github.com/opencv/opencv_contrib.git -b 4.6.0Make実行。Targetは13以降で使いたいので13に設定してるが適宜変更
python3
【Swift】配列から特定要素を削除
# はじめに
配列から特定の要素を削除したい時に見る用記事# 実装
基本はこっちを使う
```swift
array.removeAll { $0.id == "001" }
return array
```
:::note alert
エラー
```
Cannot use mutating member on immutable value: 'xxx' is an immutable capture
```
:::このようなエラーが出る場合はこっちを使う
```swift
let newArray = array.filter { $0.id != "001" }
return newArray
```# 参考記事
https://softmoco.com/swift-basics/swift-array-remove.php
UIKitとSwiftUIのViewの描画周りで気をつけること
## 気をつけることと両者の違い
結論から言うと、気をつけるべきことは、`クラスの性質`と`構造体の性質`に注意するということ。
また、両者の違いは、主に`UIkitはクラスでViewが作成され、SwiftUIは構造体でViewが作成される`ことである。## このトピックにおけるUIKitの性質
- クラスの生成
- 通常、クラスで作成したインスタンスは、アプリのライフサイクル内で一度生成されると、(自分でインスタンスを破棄するコードを書くなど以外で)`そのインスタンスはほとんど破棄されることはなく保持される。`そのため、`データや設定が安定して維持される。`- いつクラスのインスタンスが破棄されるのか?
- 通常は、`ViewController自体が破棄されるときに一緒に破棄される。`
- 破棄されるタイミングの具体例
- ユーザーが画面上の戻るボタンを押して前の画面に戻ると、現在のビューコントローラーが破棄される。
- メモリ不足の状況下で、システムがビューコントローラーとそのビュ
Coordinatorクラスについて簡単にアウトプット
## Coordinatorとは?
- UIKitでのイベントをSwiftUIで管理する(取得するなど)ために作成するクラスのこと。
- 先述した通り、主な役割としては、`UIKitのイベントやデータの受け渡しをSwiftUIに伝える。`
- (ラップされた)UIKitのViewの`delegate`や`target action`をハンドリングしたい場合、structではハンドリングできないため、Coordinatorクラスという仕組みが採用されている。- Coordinatorクラスはデフォルトで存在しないため、独自で実装する必要がある。一般的にはCoordinatorという命名である。
## 主なメソッド
`makeCoordinatorメソッド`
- makeCoordinatorメソッドは`makeUIViewメソッドよりも先に呼ばれる`ので、そこ(makeCoordinatorメソッド内)でCoordinatorを作成する。- その後、makeUIViewメソッドやupdateUIViewメソッドなどで渡されるcontextにco
UIViewRepresentableプロトコルについて簡単にアウトプット
## UIViewRepresentableプロトコルとは?
UIKitのViewや機能をSwiftUIでも使えるようにする`ラッパー的役割`を持つ。ちなみに、ラップして違うフレームワークを使用可能にする組み合わせは下記である。
- UIKitをSwiftUIで使用 → UIViewRepresentableプロトコル
- SwiftUIをUIKitで使用 → UIHostingControllerクラス## 主なメソッド
- `makeUIViewメソッド`
- 表示するViewの初期状態のインスタンスを作るメソッド。SwiftUIの中で使用したいUIKitのViewを戻り値として返す。
- 最初の一回しか呼び出されない。そのため、Viewを更新する場合はupdateUIViewメソッドに処理を定義する。- updateUIViewメソッド
- 表示するViewの状態が更新されるたびに呼び出され、更新を反映させる。
- 例えば、UIViewRepresentableプロトコルに準拠させた構造体のプロパティなどが変更されたときに呼び出さ
モバイル端末の発熱情報をUnreal Engine上で取得する
iOSとAndroid端末の発熱状況をUE上から参照する方法を調査してみました。
まず、iOS/Androidそれぞれのネイティブプラットフォームの発熱情報について軽く説明します。
# iOSの熱ステータス
参考元:
https://developer.apple.com/documentation/foundation/processinfo/thermalstate* nominal : 通常範囲
* fair : やや上昇している
* システムの対策:ファン開始、すぐに必要されないバックグラウンドタスクの停止、等
* 推薦されたアプリの対策:バックグラウンドタスクの削減(例:バックグラウンドダウンロードの停止、DBインデックス更新の停止、等)
* serious : 高い
* システムの対策:ファンがフルスピードで稼働、パフォーマンスに影響するリソース削減(例:I/O,CPU,GPUの使用の削減、60FPS→30FPSにカット)
* 推薦されたアプリの対策:I/O,CPU,GPUのようなシステムリソースの使用の削減(例:グラフィック品質設定を低に
【SwiftUI】バッジの見た目を変更する
# はじめに
iOS17から`badgeProminence`というバッジの見た目を変更するメソッドが追加されていたので使ってみました# 実装
### standard
```diff_swift
List(0..<10) { index in Text(index.description) .badge(index) } .badgeProminence(.standard) ```### decreased
```diff_swift
List(0..<10) { index in Text(index.description) .badge(index) } .badgeProminence(.decreased) ``` iOS17以降から使えるObservationについて## はじめに
iOS17以降から`Observation`という新たな状態監視のFrameworkが使用できるようになりました。
しかし、状態監視のFrameworkとしてはすでに`Combine`が存在しています。
今回は新たに登場した`Observation`と`Combine`を比較しながら、`Observation`について見ていきます。## `Observation`について
まずは、`Observation`と`Combine`の書き方を比較していきます。
今回はボタンをタップすると表示されている数字がインクリメントしていくViewをそれぞれ作成して比較していきます。### `Combine`による状態監視
`CounterViewState`は`ObservableObject`を実装し、`@Published`を付与したプロパティの値を監視しています。
`CounterView`は`StateObject`を使って`CounterViewState`を監視可能なオブジェクトとしてインスタンス化することで、`CounterViewState`の状態が変化した際に
モバイルアプリのアクセシビリティ対応(スクリーンリーダー、VoiceOver)
# はじめに
以前に[プロジェクトで行ったVoiceOver対応(読み方の変更)](https://qiita.com/repepe2en/items/42c8dc1e679a31c96c24)を投稿しましたが、今回はアプリ全体で行った対応について、目標にしているところとその対応方法をまとめて備忘録としてまとめます。自分の参加しているプロジェクトでは[Apache Cordova](https://cordova.apache.org/)というモバイルアプリ開発向けのフレームワークをベースに開発を行っています。
技術的には3割ほどネイティブの実装で他はwebの技術を利用しています。
なので、iOS,Androidとタグにありますが、この記事ではHTML,TypeScriptでの対応方法です。# 方針
[Web Content Accessibility Guidelines (WCAG) 2.0](https://waic.jp/translations/WCAG20/Overview.html)に準拠したアプリの実現。
[WAI-ARIA](https://develope
Web Share API で、canvasに描画した画像と、指定したハッシュタグをTwitterの投稿にコピーペーストする
## 使用想定シーン
画像合成して特定のハッシュタグでつぶやくキャンペーンの時に、サーバーや端末に合成画像を保存させずにコピーペースト操作でハッシュタグと画像をツイートしてもらう。### html
```
```
### script
```
const previewCanvas = document.getElementById('js-previewCanvas');
const previewImage = d
【SwiftUI】ScreenTimeAPIで特定のアプリを一定時間全く使用できないよう制限する
本記事ではScreenTimeAPIを用いて、他のアプリの使用を制限する方法を紹介します。
## はじめに
作業をしている途中に、つい息をするようにXを開いてしまい、集中が途切れてしまうことは誰にでもあると思います。
AppleにはScreenTimeAPIという機能が用意されており、他のアプリを制限できるようカスタマイズすることが可能です。## ScreenTimeAPIとは
WWDC2021にはScreenTimeAPIが発表され、`FamilyControls`、`ManagedSettings`、`DeviceActivity`という3つの新しいフレームワークが導入されました。
- **Family Controls**
ScreenTimeAPIへのアクセスを認証。アプリやウェブサイトを識別するために使われる透過トークンを提供して、ユーザープライバシーを保護する。- **ManagedSettings**
ScreenTimeで設定可能な制限を適用し、アプリの使用制限や、Webサイトのフィルタリング等の、アクティビティを制限すること可能。今回は上記2つのフ
【Swift】特定の要素の次の要素、前の要素を取得する
# はじめに
やりたいことはタイトルの通りです。
1番前にいる時に前の要素を取得しようとすると、1番後ろの要素を取得したいです
1番後ろにいる時に前の要素を取得しようとすると、1番前の要素を取得したいです# 実装
```swift
struct XXX {
let id: String
}let array: [XXX] = [XXX(id: "000"), XXX(id: "001"), XXX(id: "002"), XXX(id: "003"), XXX(id: "004")]
let selectedItem = XXX(id: "003")
func currentItemIndex(selected: XXX, in array: [XXX]) -> Int? {
if let index = array.firstIndex(where: { $0.id == selected.id }) {
return index
} else {
return nil
}
}func previousI
非日本語圏日本語フォント問題、SwiftUIにおける対処事例(2023年中旬)
デバイスの言語設定で日本語を選択していないような場面において、日本語文章のフォントが想定外のものになる現象は多くのデバイスで発生する。
![例.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3564662/c5929b30-7929-3770-da82-ba9ad7fb94f6.png)
今回は2023年中旬にAppleプラットフォーム向けアプリに実施したSwiftUIにおける対処事例を紹介する。
# 参考
2015年に公開された下記のブログポストを参考にした。このポストでは「本現象の解説」と「UIKit環境におけるNSAttributedStringを用いた解決策」を示している。また、本現象のことを「中華フォント現象」と呼んでいる。https://qiita.com/usagimaru/items/46c27c42e862fb8aba7e
# 対象アプリ
https://apps.apple.com/app/id1620268476
![アプリ.png](https://qiit
古いバージョンのXcodeをインストールする方法
以下のURLから対象のXcodeのバージョンを見つけてファイルをダウンロードする
https://developer.apple.com/download/all/?q=Xcode
SwiftUI ProgressViewのカスタマイズでできること・できないこと
# はじめに
本記事で取り上げるカスタマイズの内容はユースケースが限定的ですが、誰かしらのためになれば嬉しいです。
Horizontalな進捗バーを扱います。# 標準のスタイル
`value`に0.0〜1.0を指定すると、進捗バーを実装できます。```swift
ProgressView(value: 0.5)
```![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81715/2ad4be00-0075-8c3d-6a01-0db5a34454eb.png)
# バーの色を変える
`tint(_:)`を使うとバーの色を変えることができます。```swift
ProgressView(value: 0.5)
.tint(.green)
```![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81715/b3693810-eb92-96fd-4d88-41791d486
[iOS] Firebase Authenticationで匿名認証してからAppleIDと紐付ける方法
iOSアプリでは初回登録時にログインを必須にするとリジェクトされてしまい、初回ユーザーはログインなしで使ってもらうようにする必要がでることがあります。
これについてはFirebaseの[匿名認証](https://firebase.google.com/docs/auth/ios/anonymous-auth?hl=ja)を使うことで対応できます。
ただこれだけだと機種変時にデータが受け継がれないので、あとでなんらかのアカウントと紐づけできるようにしておく必要があります。ここではAppleIDでの連携について説明します。
## 環境
- Xcode14
- Firebase 10.14.0## 匿名認証
[公式ドキュメント:Apple プラットフォームで Firebase 匿名認証を行う](https://firebase.google.com/docs/auth/ios/anonymous-auth?hl=ja)
### Firebaseコンソール側
- Firebase コンソールの [Authentication] セクションで、[Sign-in method] の
Flutterってどうなん?実際に商用アプリ開発で使ってみた感想
これまで3年ほどWebエンジニアとして働いており、いろいろあって今年からFlutterでモバイルアプリを開発しています。
Flutterを使い始めて半年が経ったので実際に使ってみて感じたいいと思ったところとイマイチだと思ったところを紹介したいと思います。
# Flutter とは?
Flutter は 複数のプラットフォームに対応したオープンソースなフレームワークです。現在では、Android・iOS・Web・Windows・MacOS・Linuxに対応しており、単一のコードで複数のプラットフォーム上で動作可能なアプリケーションを作成することができます。
https://flutter.dev/
# 実際に使って感じたいいところ、イマイチなところ
## いいところ
### 学習コストは意外と高くない
Flutterでは、Dartという言語を使います。
https://dart.dev/
個人的な感想としては、Javascript, Typescript に似ているなーと思っています。
なので、Webをずっと触っていた私はすんなりと入ることができました。型定義がで
【SwiftUI】PhotosPicker使ってみた
# はじめに
PhotosPickerを使ったことがなかったので次回からスムーズに使えるように`PhotosPicker`の最小単位を記録しておきます。# 実装
### 写真を1枚選択する
```swift
import SwiftUI
import PhotosUIstruct SwiftUIView: View {
@State private var selectedPhoto: PhotosPickerItem?@State private var uiImage: UIImage?
var body: some View {
VStack {
if let uiImage {
Image(uiImage: uiImage)
.resizable()
.scaledToFit()
.padding(20)