iOS関連のことを調べてみた2022年09月01日

iOS関連のことを調べてみた2022年09月01日

Diffable DataSource 入門

## 概要

iOS 13 から `UICollectionView` / `UITableView` に表示するデータを管理する方法として `UICollectionViewDiffableDataSource` / `UITableViewDiffableDataSource` が登場しました。 Diffable DataSource を使うことにより、以前までの方法と比べて宣言的に書くことや美しいアニメーションのサポートも受けることができますが、一見すると登場人物が多く複雑に見えます。この記事では、 Diffable DataSource を触ったことがない人でもざっくりとその使い方が理解できるように Diffable DataSource の基礎知識をまとめます。そのための例として Todo アプリを取り上げ、以下の順で作っていきます。その過程で一通り Diffable DataSource の使い方が理解できるようにします。

– Todo アプリの最小構成を作る
– Todo を削除できるようにする
– Todo を編集できるようにする
– セクションヘッダを追加する

元記事を表示

初学者のswift学習アウトプット

iOSアカデミアで学んだ学習内容を適時アップしていこうと思います。

学習内容

・「protocol」:複数のクラスで共有するメソッドを記述。protocol名を付けたclassには、protocolで記述したメソッドを記述しなければならない。

・「Delegate」:あるクラスの処理完了時に他のクラスの処理を実行させる。delegateを受け取る側のクラスには、以下のように定義しなければならない。

“`
「例」:変数名.delegate = self
“`
・「Extension」:クラスや型に拡張機能を持たせる構文。拡張機能とは、メソッドや変数を定義でき、一部のクラスや型に機能を持たせた場合に使用。swiftファイルを分割し見やすいコードになる(リファクタリング?)。

Xcode

・「navigator area」:画面左側のカラム。【command + 0】で表示非表示の切り替えができる。
・「storyboard」:アプリの画面を作成するためのファイル
・「editor area」:中央に表示さ

元記事を表示

【SwiftUI】fullScreenCoverがあるならhalfScreenCoverがあっても良くない?

# はじめに
iOS15から`UISheetPresentationController`が使用できるようになり、簡単にハーフモーダルを実装できるようになりました。
SwiftUIでも使えるように`halfScreenCover`として実装します。

# 完成形
`fullScreenCover`と全く同じように使えるようにします。
![スクリーンショット 2022-08-31 17.32.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/09072711-85e5-4953-59e1-15ab90352f85.png)

![Simulator Screen Recording – iPhone 12 – 2022-08-31 at 18.11.50.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/8824f61f-73f8-556f-3ed9-7c6a3609a35c.gif)

元記事を表示

非表示 App の配信 (Unlisted app distribution) を実際に利用してみた

## 非表示 App の配信 (Unlisted app distribution) ってなに?

2022 年 1 月頃に導入された AppStore での新しいアプリ配信方式。

https://developer.apple.com/jp/support/unlisted-app-distribution/

大まかな特徴としては、

– 通常のストア公開アプリと同じ
– AppStore 用のビルド
– AppStoreConnect 上のストアページのメタデータ類の整備が必要
– 公開前の審査あり
– インストール制限なし
– AppStore 上において通常の検索結果、その他リストには表示されない
– 別途用意される URL リンクを踏むことで、 AppStore 上でストアページの表示とアプリインストールが可能

といった点が挙げられます。

この「非表示 App の配信」を実際に設定する機会があったため、その際の知見をまとめてみました。

## Apple 側への申請対応
### 1. アプリを通常審査に提出

[Apple の公式サポー

元記事を表示

Firebase Crashlytics の upload-symbols コマンドを直接入手する

## 経緯

Bitcode が有効化されたアプリで、 dSYM ファイルを AppStoreConnect からダウンロード。
fastlane の `upload_symbols_to_crashlytics` アクションでこれをアップロードする CI / CD のステップを組んでいました。

https://docs.fastlane.tools/actions/upload_symbols_to_crashlytics/

Firebase Crashlytics には dSYM ファイルをアップロードするためのコマンドとして [upload-symbols が同梱](https://github.com/firebase/firebase-ios-sdk/blob/9.0.0/Crashlytics/upload-symbols) されており、`upload_symbols_to_crashlytics` アクションでは、この `upload-symbols` を利用して dSYM ファイルのアップロードを実施しています。

Firebase Crashlytics を Co

元記事を表示

iOS開発で作成された不要なキャッシュを削除しディスク容量を増やす

## 前提
前提条件として、以下の実行環境での動作を確認しています。

– Apple M1
– macOS Monterey バージョン 12.0.1
– Xcode Version 13.4.1

以前のバージョンや新しいバージョンでも動作するかは未検証です。

## シェルスクリプト
以下のスクリプトを実行すると不要なディレクトリ・ファイルが削除されます。
筆者の環境では数十GBのディスク容量を空けることができました。

“`sh
# DerivedData
# 中間生成ファイル。アプリ単位でビルド時に作成され
# ビルドが突然できなくなった場合などこれを消すと解消する場合がある。
# 削除すると次回のビルドが実質クリーンビルドになる。
rm -rf ~/Library/Developer/Xcode/DerivedData/*

# iOS DeviceSupport
# Xcode が iOS 実機端末との接続を認識したタイミングで作成される。
# iOS バージョンをアップデートする度に新しいディレクリが増えていく。
# 全削除して問題なし。
rm -rf ~/Libr

元記事を表示

[M1Mac]Carthageを用いてR.swiftを使う方法

# はじめに
Carthageでライブラリを入れて開発をしているのですが、R.swiftを初めて使う際に機能しなくて困っていました。
色々調べていく際に、M1Macの「Homebrewの場所がIntel製と異なる」という特徴が原因であると発覚したので、報告&改善策としてまとめます。

# 開発環境

– M1 macOS Monterey
– Swift5
– Xcode: 13.4.1
– R.swift: 6.1.0(13F100)

# R.swiftとは
Swiftプロジェクトで画像、フォント、ストーリーボードなどのリソースを簡単に取得できるようにするライブラリです。

https://github.com/mac-cain13/R.swift

これを導入するメリットは、

– リソースをキャストせずに使える
– コンパイル時のチェックにより、誤った文字列でアプリがクラッシュすることがなくなる
– リソース名が自動補完される

といった点があります。

具体的にSwiftコードで見てみると、

“`swift:R.swiftなし
let icon = UIImage(nam

元記事を表示

【SwiftUI】Viewを引数にとるViewの作成方法

# 方法
今回の例は背景色を黄色にするViewを作成しています。
“`swift
import SwiftUI

struct BackgroundView: View {
private let content: () -> T

init(@ViewBuilder content: @escaping () -> T) {
self.content = content
}
var body: some View {
ZStack(alignment: .center) {
Color.yellow.edgesIgnoringSafeArea(.all)
content()
}
}
}
“`

# 使い方
“`swift
struct ContentView: View {
var body: some View {
BackgroundView {
Text(“サンプル”)

元記事を表示

[Swift]なぜかAutolayoutの設定ができなかった(解決済)

## 状況
![Screen Shot 2022-08-25 at 9.57.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643372/212a1a40-c323-322c-e4e9-f5639c2856a4.png)

画像のようにAutoLayoutの設定ができなかった…
Xcodeの再起動やClean Buildしても変化なし。

AutoLayoutの設定ができているファイルと見比べると、インスペクターエリアの`Layout`(黄色線)が`Autoresizing Mask`になっていた!!

![Screen Shot 2022-08-25 at 9.57.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643372/2dcaf558-4d5e-23bf-9e06-a639bbcc0264.png)

`Inferred(Constraints)`に設定を変更すると、無事AutoLayoutの設

元記事を表示

ローカルサーバでスマートフォンブラウザから端末の向きを検出する

## 結論から

httpsサーバじゃないといけない

カメラを利用するのにも必要だったので、以前の記事を参考に

https://qiita.com/tkyko13/items/1871d906736ac88a1f35

“`sh
$ openssl req -newkey rsa:2048 -new -nodes -x509 -days 3650 -keyout key.pem -out cert.pem
“`

で、鍵作ったあと

“`sh
$ http-server -S -C cert.pem
“`

or

“`js:server.js
const fs = require(‘fs’)
const express = require(‘express’);
const app = express();
const https = require(‘https’);
const options = {
key: fs.readFileSync(‘./key.pem’),
cert: fs.readFileSync(‘./cert.pem’)
};
con

元記事を表示

【Xcode】Missing required module ‘XXXXX’を修正する

# はじめに
UITestでメインターゲットをインポートしようとした時に発生したエラーを治すのに苦戦したので備忘録として残しておきます。

# エラー
![スクリーンショット 2022-08-24 20.40.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/400df42e-19dd-f94d-e022-452cf8a4f8c0.png)
![スクリーンショット 2022-08-24 20.41.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/05ac928d-b5c2-c721-a8b0-05ae8f69550e.png)

“`
Missing required module ‘Purchases’
“`

# 修正方法
① プロジェクトを選択
② UITestのターゲットを選択
③ 「Build Phases」を選択
④ 「Link Binary With Libraie

元記事を表示

【Xcode】「AST Deserialization Issue」を修正した

# はじめに
実機でビルドしようと思ったら突然大量のエラーが発生しました。

# エラー
![スクリーンショット 2022-08-25 23.34.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/fb02daeb-b2b4-53ff-52f5-78260ce2ffb1.png)

“`
/Users/XXXXXXXXX/Library/Developer/Xcode/DerivedData/XXXXX-cjjyountbftezrcatmquboljpsyt/SourcePackages/checkouts/SDWebImage/SDWebImage/Core/SDWebImageCompat.h:67:10: File ‘/Users/XXXXXXXXX/Library/Developer/Xcode/DerivedData/ModuleCache.noindex/25U36CV5033SC/UIKit-2LM3EQU7VVY4O.pcm’ is not a valid pre

元記事を表示

【Flutter】navigation_bar の比較

## 初めに
Flutter には数多くのパッケージが存在し、どれを採用するか迷ってしまうほどです。
今回は navigation_bar に注目して、通常の BottomNavigationBar に加えて、 navigation_bar のパッケージのうち、特に Likes が多い三つを比較したいと思います。

## 準備
今回は以下の三つのパッケージを使用します。
+ [convex_bottom_bar](https://pub.dev/packages/convex_bottom_bar)
+ [curved_navigation_bar](https://pub.dev/packages/curved_navigation_bar)
+ [bottom_navy_bar](https://pub.dev/packages/bottom_navy_bar)

上記の三つのパッケージのバージョンを「 pubspeck.yaml 」に記述します。
パッケージのバージョンは、特に制約がなければ最新のバージョンで問題ありません。

“`yaml: pubspeck.yaml
de

元記事を表示

SwiftUI: Mapを表示してピンを立てる

自分用の時刻表アプリを作ろう、という記事を書いた時に、乗り場をタップすると、その乗り場の地図を表示できたらいいなと思ったので、調べました。

https://qiita.com/tnar-f/items/1a95429cf5e8547f0b2f

以下、調布駅北口ロータリー周辺の地図を表示し、12番乗り場にピンを立てるコードです。

“`Swift
import SwiftUI
import MapKit

// ピンを定義する構造体
struct identifiableplace: Identifiable {
let id = UUID()
let latitude: Double
let longitude: Double
var coordinate: CLLocationCoordinate2D {
CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
}
}
struct ContentView: View {
// 12番乗り場

元記事を表示

[Swift]ディレクトリ内のファイル・ディレクトリを一覧表示するサンプルコード

## やりたいこと

Swiftのファイル操作系、たまにしか使わなくて忘れてしまうので、備忘のためのサンプルコードを書いておきたいので書きます。
この記事では temporaryDirectory内のファイル・ディレクトリ一覧を表示する処理を記載する。
(サブディレクトリ以下表示なし、隠しファイル表示なし)

## temporaryDirectoryのファイル一覧サンプルコード

“`swift
func printFiles() {
do {
let tempDirContentsUrls = try FileManager.default.contentsOfDirectory(at: FileManager.default.temporaryDirectory, includingPropertiesForKeys: nil, options: [.skipsHiddenFiles, .skipsSubdirectoryDescendants])

tempDirContentsUrls.

元記事を表示

[Swift]ファイル・ディレクトリを削除する

## やりたいこと

ファイルやディレクトリを削除する。
(ディレクトリ削除の場合は、指定ディレクトリ配下を全て削除する。)

以下の2通りの指定方法での手順を記載する。

* path指定 (ただのString)
* URL指定 (URL型)

## ファイルパス指定でのファイルの削除方法

FileManager.default.removeItem(atPath:) を使う。

“`swift
func deleteFileOrDirectory(path: String) {
do {
try FileManager.default.removeItem(atPath: path)
} catch {
print(error.localizedDescription)
}
}
“`

## URL指定でのファイルの削除方法

FileManager.default.removeItem(at:) を使う。

“`swift
func deleteFile

元記事を表示

【Flutter】DatetimePicker の使い方

## 初めに
DatetimePicker とは、以下の画像のようにユーザに年月日を入力してもらうための Widget です。
生年月日の選択などに使用されます。

## 準備
まずは、[DatetimePicker パッケージ](https://pub.dev/packages/flutter_datetime_picker) を「 pubspeck.yaml 」に記述します。
パッケージのバージョンは、特に制約がなければ最新のバージョンで問題ありません。

“`yaml: pubspeck.yaml
dependencies:
flutter:
sdk: flutter

flutter_datetime_picker: ^1.5.1
“`
Pub get をして準備は完了です。

## 実装
まずは

元記事を表示

複数選択を考える

# モチベーション

Electronの勉強のために[TaskTab](https://fiplab.com/apps/task-tab-for-mac)のクローンを作っていたら複数選択で行き詰まった

## 行き詰まった理由

– 一口に複数選択といってもOSやライブラリなどで仕様が異なる
– 直感的でない仕様がある
– 複数選択のライブラリはあるがテーブルと蜜結合していることが多く使い辛い(使いたかったのはリストのため)

# 仕様を考える

> 一口に複数選択といってもOSやライブラリなどで仕様が異なる

全ての仕様を網羅することはできないので、MacのファイルマネージャーであるFinder(≒Google Slide)の仕様を目指します。

Finderの複数選択は[ibash/better-multiselect](https://github.com/ibash/better-multiselect)でほぼ分析されていますが、一部足りない仕様があったため追記しています。

“`diff_markdown:意訳
ルール

アンカー:選択を開始する位置
フォーカス:選択を終了

元記事を表示

SwiftUI: モーダルなSheetを使って別のViewを表示する

自分用の時刻表アプリを作ろう、という記事を書いた時に、乗り場をタップすると、その乗り場の地図を表示できたらいいなと思いました。

https://qiita.com/tnar-f/items/1a95429cf5e8547f0b2f

そういう時のViewの遷移に、モーダルなSheetが使えそうと思ったのでやってみました。モーダルな画面というのは、その画面での操作を終了しない限り、アプリのその他の操作ができない画面のことです。アラート画面のようなものですかね。アイディアとしては以下のようなものです。

![スクリーンショット 2022-08-27 9.32.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2517091/2c72c9cb-2c19-9f1b-4e09-6a5a16b7019d.png)

「モーダルなシートってなに?」ボタンをタップすると、

![スクリーンショット 2022-08-27 9.55.16.png](https://qiita-image-store.s3.ap-nor

元記事を表示

【SwiftUI】iOS15からWheelPickerStyleが壊れたから自作した

# はじめに
https://qiita.com/SNQ-2001/items/82711dbb3818450c2c1a

iOS15からPickerのwheelがバグが発生しました。
これはOSのバグで現時点では解決方法はないようです。

UIKitを使ってちゃんと使えるWheelPickerを作成します。

# 実装方法
“`swift:WheelPickerView
import SwiftUI

struct WheelPickerView: UIViewRepresentable {
@Binding var selection: Int

let content: [String]

init(selection: Binding, content: [String]) {
self._selection = selection
self.content = content
}

func makeCoordinator() -> Coordinator {
return

元記事を表示

OTHERカテゴリの最新記事