Personal Factory

Personal Factory

iOSエンジニアの技術ブログ

NavigationSplitViewの"Simultaneous accesses to..."クラッシュの回避方法
iOS

NavigationSplitViewの"Simultaneous accesses to..."クラッシュの回避方法

iOS 16から登場したNavigationSplitViewとSwift 5.9から登場したmacroの@Observableの組み合わせでクラッシュが発生することがあります。 この記事ではその回避方法を説明します。 動作環境 * Xcode 15 * iOS 17 クラッシュが起こる原因 ListにはSelectionValueと呼ばれる選択された保持するパラメーターが定義されています。 このSelectionValueはHashableを準拠したインスタンスを指定します。 @MainActor struct List<SelectionValue, Content> where SelectionValue : Hashable, Content : View * https://developer.apple.com/documentation/swiftui/list/#Supporting-selection-in-lists そして、NavigationSplitViewとListのSelectionValue、そしてNavigat
4 min read
UITextViewで独自のEdit Menuを表示する
iOS

UITextViewで独自のEdit Menuを表示する

実行環境 * Xcode 14.2 * iOS 16 iPhoneのメモアプリで、テキストを長押しすると出てくるメニュー。 あれを自分で作るにはどうすればいいのかを調べてみました。 そもそもあのメニューの名前はなんだろうと調べたところ、Human Interface GuidelinesにはEdit Menuという名前で紹介されていました。 Edit menus | Apple Developer DocumentationAn edit menu lets people make changes to selected content in the current view, in addition to offering related commands like Copy, Select, Translate, and Look Up.Apple Developer Documentation Edit Menuの表示
3 min read
NumberFormatterで数値を国際化
iOS

NumberFormatterで数値を国際化

個人アプリで風水アプリを作っています。佐藤タケシです。 * 玄空飛星風水 今このアプリの国際化対応をしている最中です。 玄空飛星風水は端末の方位磁石の値を読み取り、風水を判定してくれるアプリです。 こちらのキャプチャのように画面に方位磁石の値を表示しています。 値は小数点第一位まで表示しています。 この値も国際化が必要と気づいたので、そのやり方をご紹介します。 検証環境 * Xcode 14.1 * Swift 5.7.1 * iOS 16.0 * ただし、この記事で紹介するNumberFormatterはiOS 2から利用できるものです。 小数点の国際化 数値に国際化なんて必要なの?と疑問に思った方もいるかと思います。 アラビア数字を使っている限りどの国でも通用するのでは?と思う人もいるでしょう。 今回は小数点に着目しますが、実は小数点に「.(ピリオド)」を表記するのはどの国でも行われているものではありません。 世界を見渡すと、小数点の記号は主に3つの表記があります。 * イギリス式
5 min read
Xcode Cloudを個人開発で利用した感想 2022年11月版
iOS

Xcode Cloudを個人開発で利用した感想 2022年11月版

開発環境 * Xcode 14.1 * macOS Monterey 12.6 はじめに Xcode CloueはAppleが提供するAppleプラットフォームのためのCI/CDサービスです。 * https://developer.apple.com/jp/xcode-cloud/ 去年からBeta版として公開されていましたが、2022年にXcode Cloudがパブリックリリースされました。 CircleCIやBitriseなどすでにCI/CDサービスがたくさんありますが、ついにApple自身がApple開発者のためのCI/CDサービスを提供したということで、個人開発に取り入れてみました。 結果からいうと、とても良かったです。 まだまだリリースしたばかりで、機能は最低限ですが、個人開発では十分です。 逆にチーム開発としては使いづらそうな印象を受けました。 この記事では、私が個人開発で利用した内容を共有したいと思います。 皆さんのXcode Cloud利用の参考になれば幸いです。 あくまで自分の経験や感想を中心に記載するので、Xcode
4 min read
XcodeGenプロジェクトのFirebaseライブラリーをSwift Package Manager経由で追加する
iOS

XcodeGenプロジェクトのFirebaseライブラリーをSwift Package Manager経由で追加する

実行環境 * XcodeGen: 2.32.0 * Xcode 13.4.1 FirebaseをSwift Package Managerで追加したい 個人アプリで、Firebaseを利用しています。 プロジェクトの構成はXcodeGenで生成しており、FirebaseはCocoaPodsで追加させていました。 しかし、Firebase 8.0.0(2021年5月11日リリース)からSwift Package Manager(以下SPMと略します)経由で追加できるようになりました。 * Swift Package Manager for Firebase 私のプロジェクトではFirebaseのインストールがCocoaPodsの唯一の利用目的だったので、SPMに置き換えればCocoaPodsをやめれると考えました。 いろいろ調べて、XcodeGenのproject.ymlの書き方がある程度わかったのでブログに残したいと思います。 利用しているFirebaseのプロダクト 私が利用しているFirebaseのプロダクトは次の2つです。 *
3 min read
イベントレポート

2022 iOSDC Day2感想

Xcode が遅い! とにかく遅い!! 遅い Xcode をなんとかする方法 https://fortee.jp/iosdc-japan-2022/proposal/9d542893-3c30-4077-a85a-1c7ec68caa9c 資料 内容 * XCBBuildSeviceがCPU 900%でとまる * XCBBuildServiceはSPMのバグを踏み反応しなくなる->XcodeはXCBBuildServiceを反応まってXcodeも止まる * 問題のある処理をとめたい * XCBBUILDSERVICE_PATH環境変数を変更 * XCBuildServiceProxyKit * https://github.com/MobileNativeFoundation/XCBBuildServiceProxyKit * SwiftNIOベース * Xcode 14 beta2からこのバグが直ったそう🎉 めでたい * ロック機構の問題 * clang内部のllvmのロック機構でビルド遅くなる *
3 min read
2022 iOSDC Day0感想
イベントレポート

2022 iOSDC Day0感想

iOSDC Japan 2022 今年もやってきました。iOSDC Japan。 https://fortee.jp/iosdc-japan-2022 9/10の前夜祭と9/11のday2に現地で参加してきたので感想を残したいと思います。 ノートアプリのテキストエディタの解体新書 https://fortee.jp/iosdc-japan-2022/proposal/aad51596-674f-4b8a-a24b-868e84453e9a 資料 記事 https://t.co/mof246BqdQ サンプルコード https://github.com/fromkk/TextEditorSample 内容メモ * noteアプリで新しいテキストエディタを実装した際に考えを解説 * 入力した後にスクロール追従 * Drop & Drag * iPadのデザインをreadableContentGuideで良い感じに * 画像の埋め込み * ツールバーはUIToolbarではなく、UIViewで作成。UIScrollViewを入れたか
3 min read
Task.initのクロージャーに[weak self]はいらない。Task.detachedとTaskGroup.addTaskも同様
iOS

Task.initのクロージャーに[weak self]はいらない。Task.detachedとTaskGroup.addTaskも同様

2022年7月29日、インプレスR&D社よりSwift Concurrencyの解説本をリリースしました。 こちらの本は一冊でSwift Concurrencyの機能をほぼ網羅したConcurrency機能の解説本です。 日本語でSwift Concurrencyを学べる解説本はまだ少ないので、Swift 5.5からの非同期処理をうまく書きたい方には必見の本となっています。 さて、せっかくリリースしたばかりなのですが、一部のサンプルコードがあまり良いコードではありませんでした。 すでにサンプルコードのリポジトリは修正済みですが、どのような修正があったのかをこの記事で説明したいと思います。
12 min read
Swift 5.5からのSwift  Concurrencyのasync/awaitの使い方
iOS

Swift 5.5からのSwift Concurrencyのasync/awaitの使い方

Swift 5.5からはSwiftの言語機能としてConcurrencyが登場しました。 これは非同期処理、並行処理のコードを簡潔かつ安全に記述できる機能です。 async/awaitを使えば、同期処理と同じような書き方で非同期処理を記述できます。 またactor型を使えばデータ競合を防ぐことができます。 この記事ではSwift 5.5からのSwift Concurrencyの機能の一つ`async/await`の使い方を解説します。
10 min read
Swift PlaygroundでConcurrencyを使う by Xcode 13.2.1
iOS

Swift PlaygroundでConcurrencyを使う by Xcode 13.2.1

Swift 5.5で登場したSwift Concurrency。 async/awaitを使うことで、並列処理を上から下に流れるように記述することができます。 どんな風に使えるかをSwift Playgroundで試そうとしたところ、Swift Playgroundではいろいろ制限があるようなのでまとめました。 検証環境 * Xcode 13.2.1 * Swift 5.5 _Concurrencyをインポートする Swift Concurrencyの機能をSwift Playgroundで使う場合、まず最初にすることは _Concurrency というフレームワークをインポートすることです。 明示的にインポートしないでConcurrencyの型を実行すると「スコープにそんな型は見つからない」とエラーになります。 手元ではコンパイルエラーにはならず、実行時にエラーが表示されました。 例えば_ConcurrencyをインポートしないでTaskを実行します。 Task.detached {} するとデバックエリアにこのようなエラーが出力されます。 error: reque
2 min read
iOS 15でNavigationBarとTabBarがデフォルトで透過される
iOS

iOS 15でNavigationBarとTabBarがデフォルトで透過される

iOS 15をXcode 13以上で開発していたところ、NavigationBarとTabBarの背景が透過されていることがわかりました。 どうやらXcode 13でビルドをした場合、iOS 15のNavigationBarとTabBarはデフォルトで背景が透過されるようです。 私のアプリでは透過ではなく、iOS 14以前と同じように背景色をつけたかったので、どう修正するのかを調べました。 開発環境 * Xcode 13.2 * iOS 15.2 NavigationBarをiOS 14以前と同じ見た目にする 背景色が透過されるようになった原因 UINavigationBarにはscrollEdgeAppearanceというプロパティがあります。 UINavigationBarAppearanceというNavigationBarの外観設定を司るクラスのインスタンスです。 Navigation ControllerがNavigation BarとScroll Viewを持っている場合で、Scroll Viewのコンテンツの端がNavigation
3 min read
[iOS]枠線の上にViewを乗せようとしたらviewとlayerの重なり順に苦しんだ話

[iOS]枠線の上にViewを乗せようとしたらviewとlayerの重なり順に苦しんだ話

Viewに枠線をつけて、その上にViewを乗せるコードを書いていたらUIViewとCALayerの重なり順に手間取ったのでメモ的に記事にします。 souce code https://gist.github.com/SatoTakeshiX/1b9050a7ea517785e3b45ace0a38a5ac 実行環境 * Xcode 13 * iOS 15.0 * Swift 5.5 (とはいえ、内容はiOS 15でなくても動きます) 枠線の上にViewを表示したい UIViewに枠線をつけて、その上にバッチのようにUIImageViewを乗せようとしました。 ちょうど次の図のようなレイアウトです。 最初の方針として「UIViewのlayerプロパティで枠線をつけて、その上にUIImageViewを表示するAuto Layoutを設定すればよいだろう」と思っていました。 そこでこんなコードを実装しました。 SignboardというViewに緑の枠線を表示するboardViewとその上に王冠のImage ViewであるcrownImageViewを乗せるコードです。
3 min read
VNDetectRectanglesRequestのminimumSizeについて
iOS

VNDetectRectanglesRequestのminimumSizeについて

Visionフレームワークを触っていてわからなかったことがあります。 VNDetectRectanglesRequestのminimumSizeプロパティの意味です。 minimumSizeプロパティは検出する矩形の最小サイズを指定するプロパティです。 分析する画像の矩形が指定したものよりも小さければ、分析処理をしません。 多くの矩形を分析する際は処理を軽くするために指定すると良いものです。 デフォルトが0.2になっており、0.0から1.0の値が指定できます。 let request = VNDetectRectanglesRequest() request.minimumSize = 0.2 ただこの数値の意味がわからないのです。 ドキュメント [https://developer.apple.com/documentation/vision/vndetectrectanglesrequest/2875374-minimumsize] にはこう書かれています。 > The minimum size of a rectangle to detect, as a propor
3 min read
[SwiftUI] GeometryReaderでメソッド/関数を実行したい!
iOS

[SwiftUI] GeometryReaderでメソッド/関数を実行したい!

実行環境 * Xcode 12.5 GeometryReaderでViewのサイズを取得する [SwiftUI] GeometryReaderでViewのサイズを知る [https://blog.personal-factory.com/2019/12/08/how-to-know-coorginate-space-by-geometryreader/] で解説したとおり、SwiftUIでViewのサイズを取得するにはGeometryReaderを使います。 GeometryReaderのハンドラーから渡されるGeometryProxyのインスタンスでViewのサイズがわかります。 struct LocalVariableView: View { var body: some View { GeometryReader { proxy in Text("\(proxy.frame(in: .local).debugDescription)") } } } struct LocalVariableView_
2 min read
[SwiftUI] PreviewProviderで実行されているかを確認

[SwiftUI] PreviewProviderで実行されているかを確認

確認環境 * Xcode 12.5 * iOS 14.5 SwiftUIでPreviewされているかをプログラムで確認する方法 PreviewでViewを表示している場合、環境変数のXCODE_RUNNING_FOR_PREVIEWSの値が"1"になっています。 なので、次のように場合分けをするとプログラム上Previewで表示されているかを判別できます。 var body: some View { if ProcessInfo.processInfo.environment["XCODE_RUNNING_FOR_PREVIEWS"] == "1" { Text("running on preview") } else { Text("running on not preview"
1 min read
[2021年版]XcodegenでCarthageとCocoapodsを使う最小プロジェクトを作成
iOS

[2021年版]XcodegenでCarthageとCocoapodsを使う最小プロジェクトを作成

個人アプリのプロジェクト構成をXcodegenで作り直そうかと思っています。 個人アプリはライブラリーの依存関係をCarthageとCocoapodsを使って管理していますが、Xcodegenではどういう記述でproject.ymlを書けばいいのかが検討つきませんでした。 理解を深めるために最小プロジェクトを作ることにしました。 この記事ではXcodegenでCarthageとCocoapodsを使う最小プロジェクトを解説します。 実行環境 * Xcode 12.4 * Xcodegen * Carthage: 0.37.0 * Cocoapods: ディレクトリ 今回はTryXcodegen という名前のプロジェクトを作成して、CarthageとCocoapodsでライブラリーを管理し、プロジェクト生成にXcodegenを利用します。 最終的なディレクトリ構造は次のとおりです。 主要なもののみ掲載しています。 $ tree -L 2 . ├── Cartfile ├── Cartfile.resolved ├── Carthage │ ├── Build ├
3 min read
CarthageのXcode 12エラー: This usually indicates that project itself failed to compile.を直す
iOS

CarthageのXcode 12エラー: This usually indicates that project itself failed to compile.を直す

Xcode 12でCarthageでライブラリーをビルドしようとしたら、ビルドが失敗して以下のようなエラーを出力されました。 Carthageのバージョンは0.36.0で試しています。 This usually indicates that project itself failed to compile. Please check the xcodebuild log for more details: /var/folders/jm/pyy6p95j177_btm91tj0mkdm0000gn/T/carthage-xcodebuild.WPi9jL.log > このエラーは下記issuesから引用 https://github.com/Carthage/Carthage/issues/3019 実行環境 * Xcode 12.4 * Carthage: 0.36.0 -&
2 min read
Clubhouseのスーパー楕円をSwiftUIで作る
iOS

Clubhouseのスーパー楕円をSwiftUIで作る

近年流行りだした音声SNS, Clubhouse [https://www.joinclubhouse.com/]。 デザインの特徴の1つにふわっとした丸みを帯びた楕円のアイコンがあります。 これは「スーパー楕円」と言われているそうです。 丸よりも丸みを感じる!? スーパー楕円の魅力とデザイン | Spinners Inc. [https://www.spinners.work/posts/kudakurage-superellipse-desgin/] この楕円を@tokorom [https://twitter.com/tokorom]さんがUIKitで実装してました。 スーパー楕円UIをiOS+Swiftで実装する | Spinners Inc. [https://spinners.work/posts/swift-superellipse/] この記事を読んでSwiftUIでも作りたくなったので、作ってみます。 実行環境 * Xcode 12.2 * iOS 14.2 実装方針 tokoromさんと同じようにもと記事 [https://www.spinner
4 min read
SwiftUIで開閉式メニューの作り方
iOS

SwiftUIで開閉式メニューの作り方

SwiftUIで下からニュッと表示する開閉式メニューの作り方を解説します。 > この記事は私が2020年12月22日に発表した資料、 「SwiftUIで作る開閉式メニュー [https://speakerdeck.com/satotakeshi/swiftuidezuo-rukai-bi-shi-meniyu] 」を記事化したものです。 動作環境 この記事は以下の環境で動作を確認しています。 * Xcode 12.2 * iOS 14.2 開閉式メニューを作ろう 今回作る開閉式メニューの動きをgifでみてみましょう。 親Viewを作る まずは親Viewを作りましょう。 struct ContentView: View { @State var isShowMenu = false var body: some View { ZStack { Button(action: { withAnimation { isShowMenu.toggl
4 min read
SwiftUIのデータ管理 Property Wrapper編

SwiftUIのデータ管理 Property Wrapper編

SwiftUIでアプリを開発していると@Stateや@Bindingの使い分けについて迷ったりしていませんか? SwiftUIではデータを管理するProperty Wrapperがたくさんあります。 @State、@Binding、@StateObject、@ObservedObjectなどなどです。 Property Wrapperそれぞれの特徴を理解できれば、SwiftUIのアプリ開発がはかどるでしょう。 今回はSwiftUIのデータ管理を行うProperty Wrapperの使い分けについて解説します。 > この記事は私が12月9日に発表した資料、 「SwiftUIのデータ管理 [https://speakerdeck.com/satotakeshi/swiftuifalsetetaguan-li] 」を記事化したものです。 SwiftUIのデータ管理記事一覧 * SwiftUIのデータ管理 Single Source of Truth編 [https://blog.personal-factory.com/2021/01/20/whats-the-single
7 min read
SwiftUIのデータ管理 Single Source of Truth編
iOS

SwiftUIのデータ管理 Single Source of Truth編

SwiftUIでアプリを開発していると@Stateや@Bindingの使い分けについて迷ったりしていませんか? SwiftUIではデータを管理するProperty Wrapperがたくさんあります。 @State、@Binding、@StateObject、@ObservedObjectなどなどです。 Property Wrapperそれぞれの特徴を理解できれば、SwiftUIのアプリ開発がはかどるでしょう。 今回はSwiftUIのデータ管理に欠かせないSingle Source of Truthという考え方について解説します。
3 min read
UITableViewをコードで実装する最速の方法
iOS

UITableViewをコードで実装する最速の方法

UITableViewでリスト表示を実装するさい、よくやるやり方は、StoryboardやXibファイルでCellを作って、そのidentifierをView Controllerで指定する方法です。 ですが、UITableViewCell標準の表示で十分な場合にファイルが分かれるのは面倒です。 なんとかコードで済ます方法がないかと探したらありましたのでご紹介します。
2 min read