- 投稿日:2022-02-23T22:01:54+09:00
個人開発で初めてiOSアプリをリリースした備忘録
目次 はじめに 私のスキル 難しかった点 良かった点 さいごに はじめに 先日、初めて個人としてiOSアプリをリリースしました。 リリースまでの期間は約3ヶ月でした。まだまだ知らないことも多く、大変学びのある経験でした。 そこで今回は、リリースまでの過程で感じたことや気づいた点について書きました。 これから個人開発をしてみたい方、現在個人開発をしている方の役に立つかもしれません。 私のスキル まずは簡単に私のスキルについて紹介します。 個人開発は前提知識がどれくらいあるかで難易度が変わるので、参考になれば幸いです。 現役のiOSエンジニア。iOSアプリの開発やリリース経験あり。 基礎的なSwiftの記法、Xcodeの使い方、リリース方法について理解している。 エラーや分からない事があっても、検索等を駆使して多くの場合は解決できる。 難しかった点 ⭐️スケジュール管理が難しい 私の場合、基本的には平日仕事をしながら隙間時間で個人開発を進めていました。 基本的には仕事の状況を見ながら、ちょこちょこ進めていくのですが、時間の使い方が難しかったです。 個人開発はリリースするタイミングが完全に自分次第なので、 時間を割けず開発が長期間になってモチベーションが続かなくなったり、 反対に「早く出したい」という気持ちが先行してつい睡眠時間を削ってしまうこともありました。 実際にリリースして感じましたが、開発ペースに波があることはあまり気にしなくて良いと思います。良いものをしっかり考えて十分に時間をかけた方がユーザーに喜ばれるサービスになるはずです。 ⭐️デザイン難しい アプリをリリースする為には、App Storeに提出するスクリーンショットやアプリアイコン等の準備が必要になります。思っていたよりもこれらの準備に時間がかかりました。そしてデザインを自力で全てやろうとすると結構難しいです。 私はデザインの知識がほとんどなく、ツールの使い方もあまり詳しくありませんでした。 私の場合は、デザイナーさんに依頼したり、便利なツールを駆使することでこれらを解決しました。 ココナラなどデザイナーさんに依頼できるサービスもあるので、上手に活用したいですね。 画面のデザインについても素人なので、どういう風にすべきかかなり悩みましたが、こちらはAppleのHuman Interface Guidlinesや様々なアプリのUIを参考にしました。 アプリのUIについては、Playというアプリで様々なUIをお試し作成しましたが、とても良いサービスなのでぜひ使ってみてください。 ⭐️細かい部分が気になってしまう 開発を進めていると、既にできている箇所に対して「ボタンの配置を変えたい」「この機能も追加したい」という様な思いが出てくることがあります。こうなるといつまでもリリースまで辿り着けません。 もしアプリをリリースしたいと考えている方は以下の2点を意識すると良いです。 設計やデザイン、提供したい機能を明確にしてから実装する。最初にしっかり時間をかけた方が良いです。結果的に手戻りが減って早くリリースできます。 最低限の機能だけを実装する。まずはリリースして改善していく方がユーザーの反応も分かります。 ⭐️サービス名を考えるのが難しい サービス名考えてくれるサイトもあるので、必要に応じて活用すると良いです。 良かったこと ⭐️自分が作ったアプリがApp Storeに並ぶ達成感を味わえる。自信になる。 自分の作ったアプリがApp Storeに並ぶまでは数多くの壁があります。 アプリの企画・設計から開発、リリース審査に向けた対応など。個人開発ではこれらを一人で解決しながら進めていく必要があります。その為、無事に審査が通った時にはうれしくて感動します。そしてこれらを成し遂げたということが自信になります。 ⭐️とにかく楽しい 自分のペースで開発を進めたい。新しい技術を試したい。自分で考えたサービスを出してみたい。このような思いを持ったエンジニアにとって個人開発は最高です。 好きなだけコードを書けますし、どんな書き方も出来ます。コードを書くのが好きな人だったら個人開発は楽しくて仕方ないです。 ⭐️技術力がアップする 新しい技術を試したりリリースまでの準備をしていると必ず壁にぶつかります。 これらを自力で解決したり自分の頭で考えることで課題解決能力や開発の技術力が向上します。 一人で全てやることでリリースまでの一連の流れをしっかり理解できますし、チーム開発のありがたさも感じます。 さいごに アプリの開発をひとりでやるのは大変な点もありますが、学びが多くエンジニアとしての自信にもなるのでかなりオススメです! 最後に私がリリースしたアプリのリンクを記載するので、もし興味をもってくださった方がいたら、覗いてみてください! DIG IT(ディグ イット)
- 投稿日:2022-02-23T16:55:40+09:00
On Demand Resourcesを使う(Swift Concurrency対応)
個人アプリでOn Demand Resourcesを使いたいところがあり、以下の記事を参考に導入してみました。 https://qiita.com/kukimo/items/39a0eeb40626a4cd364f https://www.raywenderlich.com/520-on-demand-resources-in-ios-tutorial 仕組みや手順は公式ドキュメントと上記記事を参照するのが早いと思います。 Swift Concurrencyで以下のようなユーティリティを作っておくとより簡単に導入できるよというお話。 ResourceLoader.swift import Foundation /// On Demand Resourceの読み込みを支援 final class ResourceLoader { static let `default` = ResourceLoader(bundle: .main) private let bundle: Bundle private init(bundle: Bundle) { self.bundle = bundle } /// tagで指定されたOn Demand Resourceを読み込む /// onSuccessで、実際のリソース読み込み処理を実装する func load<R>( tag: String, onSuccess: () throws -> R ) async throws -> R { let request = NSBundleResourceRequest(tags: [tag], bundle: bundle) if await request.conditionallyBeginAccessingResources() { // リソースは端末にダウンロードされている } else { // 端末にリソースをダウンロード try await request.beginAccessingResources() } return try onSuccess() } } 使い方はこんな感じ。 let image = try await ResourceLoader.default.load( tag: "MoreImages", onSuccess: { UIImage(named: "more_image1") } ) let url = try await ResourceLoader.default.load( tag: "MoreSounds", onSuccess: { Bundle.main.url(forResource: "sound", withExtension: "mp3") } )
- 投稿日:2022-02-23T13:23:42+09:00
Swiftで端末情報を取得するコード
Swiftでスマホやタブレットの端末情報を取得する方法。 ソースコード // UDID UIDevice.current.identifierForVendor!.uuidString // UUID UUID().uuidString // デバイス名 UIDevice.current.name // システム名(iOSなど) UIDevice.current.systemName // システムバージョン(15.1など) UIDevice.current.systemVersion // キャリア名(ソフトバンク、ドコモなど) CTTelephonyNetworkInfo().subscriberCellularProvider?.carrierName // Mobile Country Code(MCC)(440など) CTTelephonyNetworkInfo().subscriberCellularProvider?.mobileCountryCode // Mobile Network Code(MNC)(10など) CTTelephonyNetworkInfo().subscriberCellularProvider?.mobileNetworkCode // ISO 3166 country codes(jpなど) CTTelephonyNetworkInfo().subscriberCellularProvider?.isoCountryCode 参考
- 投稿日:2022-02-23T12:21:55+09:00
SwiftUI Tutorial の復習
記事の内容 SwiftUI Tutorial の復習 アプリの内容 阪急神戸線の駅一覧 駅一覧のデータは JSON で用意した JSON をアプリで解析する 駅周辺の地図と駅名・駅ナンバーを表示 iPhoneSE(2nd Generation) ライトモード iPhoneSE(2nd Generation) ダークモード Mac 開発環境 ハードウエア 項目 PC MacBook Air(M1,2020) メモリ:16GB ストレージ:1TB 実機 iPhoneSE(2nd Generation 128GB iOS 15.3.1) PCと実機を接続する USB-C Digital AV Multiportアダプタ ソフトウエア 項目 言語 Swift 5.5.2 IDE Xcode Ver 13.2.1 その他 Visual Studio Code Ver 1.64.2 バージョン管理 GitHub サンプルデータ(JSON)を作成する際の注意点 JSON のキーと Codable のプロパティの表記を揃える Codable Station.swift struct Station: Hashable, Codable, Identifiable { var id: String var name: String var nameEnglish: String var latitude: String var longitude: String // メソッド等は省略 } 正しいサンプルデータ(JSON) JSON [ { "id": "01", "name": "大阪梅田", "nameEnglish": "Osaka-umeda", "latitude": "34.705326", "longitude": "135.498398" }, { "id": "02", "name": "中津", "nameEnglish": "Nakatsu", "latitude": "34.709851", "longitude": "135.492499" } ] Codable のプロパティと表記が一致しないためエラーが発生する JSON [ { "ID": "01", "駅名": "大阪梅田", "駅名(英語)": "Osaka-umeda", "緯度": "34.705326", "経度": "135.498398" }, { "ID": "02", "駅名": "中津", "駅名(英語)": "Nakatsu", "緯度": "34.709851", "経度: "135.492499" } ] NavigationLink は NavigationView の中に書く StationListView.swift import SwiftUI struct StationListView: View { var body: some View { NavigationView { List(stations){ station in NavigationLink { StationDetail(station: station) } label: { StationRow(station: station) } } .navigationTitle("阪急神戸線") // navigationTitle は List の } 直後に書く } } } struct StationListView_Previews: PreviewProvider { static var previews: some View { StationListView() } }
- 投稿日:2022-02-23T11:11:34+09:00
【SwiftUI】Toggleを用いてチェックボックスを作る
SwiftUIでチェックボックスを実装する方法の1つとして、ToggleStyleのカスタムクラスを追加する方法があります。 ToggleStyleとは、Toggleの外観と動作を定義するモディファイアです カスタムクラスを実装する struct CheckboxStyle: ToggleStyle { func makeBody(configuration: Configuration) -> some View { // チェックボックスの外観と動作を返す return HStack { Image(systemName: configuration.isOn ? "checkmark.circle.fill" : "circle") .foregroundColor(configuration.isOn ? .blue : .black) .font(.system(size: 28, weight: .semibold, design: .rounded)) configuration.label } .onTapGesture { configuration.isOn.toggle() } } } configurationからisOnやlabelが取得できるので、Toggleがオンとオフの時の外観をmakeBody(configuration:)に書いています。 onTapGestureを追加してタップされた時にisOnを更新します。 カスタムスタイルを指定する @State private var isChecked: Bool = false var body: some View { Toggle(isOn: $isChecked) { Text("チェックボックス") .font(.system(.title2, design: .rounded)) .fontWeight(.heavy) .foregroundColor(isChecked ? .blue : .black) .padding(.vertical, 12) } .toggleStyle(CheckboxStyle()) } .toggleStyleに作成したカスタムクラスを指定します。 実行結果 isOn = false isOn = true makeBody(configuration:)の返すViewを変更することで色々な見た目のチェックボックスを実装することができます。
- 投稿日:2022-02-23T05:25:01+09:00
iPhoneアプリの基本Menuを作成(#1構成編)
XCode12を使用したSWRevealViewControllerによるサイドバーメニューの作成。 下記の様なスライド式のメニュー。 xcode内のStoryboardの構成は下記様です。 メニュー概要 AnimalNoteと言うアプリ(ペットの医療情報管理)の最小メニュー構成。 Menu1 AnimalNoteアプリ部。 Menu2 最新情報アプリの最新情報Webサイト表示部。 Menu3 アプリ利用者QR登録、及び操作マニュアルサイト表示部。 上記のような構成として作成。 参考サイト(YouTubeサイト参考に作成) https://www.youtube.com/watch?v=EWDNScxZ0YU&t=1220s 次回は作成準備等をYouTubeにて解説。
- 投稿日:2022-02-23T03:21:11+09:00
Swiftでお手軽ストップウォッチ実装
今回はシングルトンを使ったストップウォッチの実装を行いました。 現在私が作っているアプリがどうしてもスピード勝負になることが想定され、どのメソッドが一番処理に時間をかけているか調べる必要があったため、手軽に使えるように自分なりにコーディングしてみました。 #Code? import Foundation class StopWatch: NSObject { private static let measure: StopWatch = .init() private override init() {} var watches: [String : Date] = [:] static func start(label: String) -> Void { let start: Date = Date() measure.watches.updateValue(start, forKey: label) } static func stop(label: String) -> Void { guard let start: Date = measure.watches[label] else { fatalError("Label doesn't exist.") } let time: TimeInterval = Date().timeIntervalSince(start) measure.watches.removeValue(forKey: label) print(label, time) } } #Usage⚽️ 結論としては、使い方はこのようになります。 StopWatch.start(label: "アルファベットの冪集合を導出") //冪集合を導出する(など、重い処理) StopWatch.stop(label: "アルファベットの冪集合を導出") // アルファベットの冪集合を導出: 67.86 seconds // ↑このようにプリントされる ちなみに冪集合とは、ある集合の全ての部分集合を元にもつ集合で、例えば{A, B}の冪集合は{Φ, {A}, {B}, {A, B}}となります。 そして要素数がNの集合の冪集合は要素の数が 2^Nとなることが分かっており、 アルファベット全体のの冪集合の要素の数は2^26 = 67,108,864と膨大になります。 冪集合を計算する際の関数は再帰的に定義され、以下のように与えられます。 (参考:Find all combination of string array in swift) Powerset(冪集合) extension Array { var powerset: [[Element]] { guard count > 0 else { return [[]] } // tail contains the whole array BUT the first element let tail = Array(self[1..<endIndex]) // head contains only the first element let head = self[0] // computing the tail's powerset let withoutHead = tail.powerset // mergin the head with the tail's powerset let withHead = withoutHead.map { $0 + [head] } // returning the tail's powerset and the just computed withHead array return withHead + withoutHead } } 仕組みについては、今度コンビネーションの実装についても記事にしようと思っているのでその時に説明してみようと思います。 #Example? 上記で紹介した冪集合を使って、実際にPlaygroundで時間計測をしてみましょう。 Let's measure the time // Uまで計測 let alphabet: [Character] = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U"] // 総合計時間の計測 StopWatch.start(label: "Total time") for i in 0..<alphabet.count { // i文字目までのアルファベットの冪集合の計算時間の計測 StopWatch.start(label: "Alphabet's powerset elapse time \(i)") let powerset = Array(alphabet[0..<i]).powerset StopWatch.stop(label: "Alphabet's powerset elapse time \(i)") // カウント print("Alphabet's powerset count until \(alphabet[i])", powerset.count) } StopWatch.stop(label: "Total time") ###Result 980秒(!)かかりました Alphabet's powerset elapse time 0 0.005095005035400391 Alphabet's powerset count until A 1 Alphabet's powerset elapse time 1 0.0016039609909057617 Alphabet's powerset count until B 2 Alphabet's powerset elapse time 2 0.0014590024948120117 Alphabet's powerset count until C 4 Alphabet's powerset elapse time 3 0.002460002899169922 Alphabet's powerset count until D 8 Alphabet's powerset elapse time 4 0.008343935012817383 Alphabet's powerset count until E 16 Alphabet's powerset elapse time 5 0.012218952178955078 Alphabet's powerset count until F 32 Alphabet's powerset elapse time 6 0.24290001392364502 Alphabet's powerset count until G 64 Alphabet's powerset elapse time 7 0.48837602138519287 Alphabet's powerset count until H 128 Alphabet's powerset elapse time 8 0.39558398723602295 Alphabet's powerset count until I 256 Alphabet's powerset elapse time 9 0.35213494300842285 Alphabet's powerset count until J 512 Alphabet's powerset elapse time 10 0.6983180046081543 Alphabet's powerset count until K 1024 Alphabet's powerset elapse time 11 0.9306050539016724 Alphabet's powerset count until L 2048 Alphabet's powerset elapse time 12 1.2875239849090576 Alphabet's powerset count until M 4096 Alphabet's powerset elapse time 13 2.3467971086502075 Alphabet's powerset count until N 8192 Alphabet's powerset elapse time 14 5.930698037147522 Alphabet's powerset count until O 16384 Alphabet's powerset elapse time 15 11.123641014099121 Alphabet's powerset count until P 32768 Alphabet's powerset elapse time 16 23.158427953720093 Alphabet's powerset count until Q 65536 Alphabet's powerset elapse time 17 59.36393702030182 Alphabet's powerset count until R 131072 Alphabet's powerset elapse time 18 113.55426597595215 Alphabet's powerset count until S 262144 Alphabet's powerset elapse time 19 211.3655710220337 Alphabet's powerset count until T 524288 Alphabet's powerset elapse time 20 521.3869780302048 Alphabet's powerset count until U 1048576 Total time 980.5250370502472 なんと20文字目の U までで980秒もかかってしまいました。 このままZまでやったとしたらあと4時間かかる計算です。 Pythonだと恐らく一瞬でできるのですがいかにPlaygroundが重いかが分かると思います。 (ただ、Arrayの代わりにSetを利用するとか、Playground側の設定を変更するなどして速くすることはできます) #Conclusion? 練習がてら記事を書いてみましたが、これからも何か書きやすいネタと時間があれば書いていこうと思います。 皆さんもぜひ使ってみてくださいねー? #宣伝 「イラスト英語辞典」は最新の心理学を応用した、誰でも簡単に英単語を記憶できるアプリです! 私は前に英検一級を目指していて、最初はその単語量の多さから苦悶していました。 しかし勉強法を試行錯誤してゆく中で、「記憶するには、イラストを描くのが一番良い」 というとあるカナダの大学の心理学の論文を読みました。 半信半疑になりつつも私は藁にすがる思いで試しに落書きしながら覚えてみたところ... これがめちゃくちゃ覚えやすいことが分かりました。 確かに、わざわざ単語ごとにイラストを描くのはコストがかかりますし、そもそも絵なんか描いて覚えられるのかよ! と思うかも知れません。 ただ少なくともwatasiha、基本的には分からない単語というものがなくなり、文がスラスラ読めるようになりました。 そして何より、楽しく覚えられます!(それが一番のメリット!笑) **無料なのでぜひインストールしてみてください!**?? ? AppleStore「イラスト英語辞典は神アプリ」