投稿

ラベル(Swift)が付いた投稿を表示しています

【OSLog】How to log a Swift project

イメージ
Overview I found an article on the net that summarized how to use OSLog, I wanted a working sample. I am new to logging, so I wasn’t sure how to interpret the usage of OSLog. So I summarized it in my own way. What is OSLog? It is a library for logging that is provided by Apple and can be used in Swift projects. The official documentation is here . Sample https://github.com/Kuehar/OSLogSample When the above code is run, eight buttons are lined up as shown below. import SwiftUI import OSLog struct ContentView: View { let logger = Logger(subsystem: Bundle.main.bundleIdentifier!, category: "ApplicationCode") var body: some View { VStack { Button(action: { logger.trace("Trace Log") }, label: { Text("Trace") }) Button(action: { logger.debug("Debug Log") }, label: { Text("Debug")

SwiftUIの練習のためにGithubのリポジトリ一覧を取得して表示するiOSアプリを作った話。

イメージ
 何はともあれコードを書こう ちまちまCourseraのSwiftUI関連のコースとかの勉強を進めてはいるが、実践的なアプリを作ってみたい気持ちが出てきたので、土日を使ってサンプルを作ってみた。 ソースは ここ 。 単純なアプリなので、MVCモデルで作ればいいやの考え方で処理の書き方が分からない箇所は他に作っていた方の処理を真似しつつ、なんとか作り終わった。 仕様としては トップ画面に検索バーを用意し、入力した文字列を元にGitHubに存在するユーザーを検索する クエリで得られた結果を同画面内で行単位で表示し、ユーザーをタップした場合にはそのユーザーのリポジトリを表示する。 というもの。 ここどうすんだって迷ったポイント・他人のコードを読んでなんだこれってなったポイント ModelでGitHubとの通信をしてUserやらRepositoryの情報をfetchするのは良いけどJSON周りの処理ってどう書くんだ? →とりあえず他人がどう書いているかを見て解決。JSONDecoderで一発だった @MainActorってなに? →クラス単位で@MainActorをつけておくと、そのクラスのすべてのメソッドがメインスレッドでよばれるようになる。関数につけた場合はその関数だけが呼び出される。 今回は後者のパターン。 Taskとか初めて存在を知ったんだけどこれどういう風に使えばいいの? →そもそもasync,awaitを知るところから始めるべき。 備忘として書くと、それぞれ非同期処理を書くときに使用する書き方。asyncはメソッドが非同期作業を実行することを明確にするメソッド属性、awaitはasyncな非同期メソッドを呼び出す際に使われるキーワード。そしてTaskはプログラムの一部として非同期で実行できる作業の単位のこと。細かい書き方は省くが、それぞれの非同期処理の単位を一まとめにしてくくり、実行単位をまとめるようなイメージ。 @Publishedってなんだっけ・・・ →Combineフレームワークの一部として提供されているProperty wrapper。ObservableObjectプロトコルに準拠したクラス内のプロパティを監視し、変化があった際にViewに対して通知を行う。なお、クラス内のプロパティに付与することができるが、structなどの値型には付与できない。 他

LeetCodeのEasy問題を解いて勉強するSwift Climbing Stairs編

イメージ
LeetCodeのEasy問題を解いて勉強するSwift Climbing Stairs編 新しくSwiftを触ることになりそうなので ひとまずコードを書いてみることにする。 LeetCodeのEasy問題は比較的解き方を知っている(はず)なので、Python3で書いていた部分をどのような書き方に直すのかを色々思い出しつつ試行錯誤していく。 書いている人のレベル感 Swiftビギナー。基本的な文法すらあやふやなので始めて数日レベルと言っても過言ではない。 LeetCode お題が与えられ、その内容に合わせてコードを書き、提出して合ってるかどうかを確認できる。 問題はソフトウェアエンジニアのコーディング面接で出されたお題をそのまま引用していることがほとんど。 前回 LeetCodeのEasy問題を解いて勉強するSwift Last Stone Weight編 Climbing Stairs Climbing Stairs 階段を登るとき、頂上までn段の階段があり、仮に毎回、1段か2段のどちらかを登ることができる時、何通りの登り方が存在するかを返り値として書く。 典型的な問題でけんちょん本にも記載されていた・・・はず 単純な再帰でもテストケースは通るが、それだとnの値のよっては計算量が爆発する可能性があるため、今回はメモ化再帰で解く。 関数の引数として配列を渡すときの記述を知らず、調べた。 Swiftではそのような場合に参照渡しをするときに inout を使うようで、そして実際に呼び出す時に該当する引数の前に & を付ける。 なんか気持ち悪いと思いつつもそうしないとエラーを吐くんだからしょうがない。 あと、dpの時とかに使う配列の長さを設定して中身を何の値で埋めるか、みたいな所も勉強できた。単純な問題だけど意外と学びがあったように思える。 class Solution { func climbStairs ( _ n : Int ) - > Int { var memo : [ Int ] = Array ( repeating : - 1 , count : n + 1 ) return climb_Stairs ( 0 , n , &

LeetCodeのEasy問題を解いて勉強するSwift Last Stone Weight編

イメージ
LeetCodeのEasy問題を解いて勉強するSwift Last Stone Weight編 新しくSwiftを触ることになりそうなので ひとまずコードを書いてみることにする。 LeetCodeのEasy問題は比較的解き方を知っている(はず)なので、Python3で書いていた部分をどのような書き方に直すのかを色々思い出しつつ試行錯誤していく。 書いている人のレベル感 Swiftビギナー。基本的な文法すらあやふやなので始めて数日レベルと言っても過言ではない。 LeetCode お題が与えられ、その内容に合わせてコードを書き、提出して合ってるかどうかを確認できる。 問題はソフトウェアエンジニアのコーディング面接で出されたお題をそのまま引用していることがほとんど。 前回 LeetCodeのEasy問題を解いて勉強するSwift Invert Binary Tree編 Last Stone Weight Last Stone Weight 与えられた数値が入っている配列の中に入っている最も大きい値と2番目に大きい値をぶつける。 ぶつける時に値がイコールなら両方消える。値が異なる場合には両方とも削除し、最も大きい値から2番目に大きい値を引いた値を配列に追加する。 これを繰り返し、配列内に値が1個、または0個になるまで繰り返す。1個 残った場合はその値を戻り値として返却し、0個の場合は0を返す。 class Solution { func lastStoneWeight ( _ stones : [ Int ] ) - > Int { var stones = stones . sorted ( by : > ) while stones . count > 1 { let smaller_stone = stones . remove ( at : 1 ) stones [ 0 ] - = smaller_stone stones = stones . sorted ( by : > ) } return stones [ 0 ]

Courseraの"Create the User Interface with SwiftUI"に入門した話。

イメージ
Create the User Interface with SwiftUI タイトル通り、Courseraの以下のコースに入門しました。 Create the User Interface with SwiftUI 参考本を一通り復習し終わったが、いまいち全体的な開発サイクルを理解できなかったのでSwiftUI周りの開発をどのように進めていくのかを実践的に勉強できるコースを探していたところ、Metaが提供しているコースがあったので入門したという流れ。 今日の0時ごろに登録して1時間半くらい軽く進めて"Setting up SwiftUI"を完了したのでそこで学んだことを備忘的に残しておく。 Appleのデバイスには一般的なコンピューター(MacBook,iMacなど)とタッチデバイス(iPhone,Apple Watchなど)に大別される。 上記のうち前者は操作の精度が高いが、後者はディスプレイの小ささなどから捜査の精度が低い。よってデバイス上に表示される情報はシンプルに、そして情報量を制限するべきである。 気になる人は Human Interface Guideline 見てね!とのこと。 また、UI的に配色にも注意する。例として挙げられていたのはボタンの配色が全体的に暗いと分かりにくいから操作しやすいように明るい配色にしよう!みたいな話。 SwiftUIの利点 ダイナミックテキスト(デバイスごとに表示されるテキストのサイズ)が自動的にサポートされていること アクセシビリティ(障がい者向けの対応)やローカライゼーション(異なる言語区分への対応)などがしやすいこと ライトテーマやダークテーマに対応が容易なこと 宣言的(Declarative)シンタックスと命令的(Imperative)シンタックスの違い Declarative = WHAT you want つまり結局何がしたいのかに集約される。(ハンバーガーを注文するときにハンバーガー下さい。で通用する) Imperative = HOW you want どのように用意するのかに集約される。(ハンバーガーを注文するときにパンを用意して、トーストして、肉を焼いて、etc...したものを下さいというようなもの) つまりDeclarativeは処理を書けばマシン側で自動的に最適化をして欲しいもの

LeetCodeのEasy問題を解いて勉強するSwift Invert Binary Tree編

イメージ
LeetCodeのEasy問題を解いて勉強するSwift Invert Binary Tree編 新しくSwiftを触ることになりそうなので ひとまずコードを書いてみることにする。 LeetCodeのEasy問題は比較的解き方を知っている(はず)なので、Python3で書いていた部分をどのような書き方に直すのかを色々思い出しつつ試行錯誤していく。 書いている人のレベル感 Swiftビギナー。基本的な文法すらあやふやなので始めて数日レベルと言っても過言ではない。 LeetCode お題が与えられ、その内容に合わせてコードを書き、提出して合ってるかどうかを確認できる。 問題はソフトウェアエンジニアのコーディング面接で出されたお題をそのまま引用していることがほとんど。 前回 LeetCodeのEasy問題を解いて勉強するSwift Binary Search編 Invert Binary Tree Invert Binary Tree 与えられたバイナリツリーをInvert(反転)させて root を返す関数を書く。 /** * Definition for a binary tree node. * public class TreeNode { * public var val: Int * public var left: TreeNode? * public var right: TreeNode? * public init() { self.val = 0; self.left = nil; self.right = nil; } * public init(_ val: Int) { self.val = val; self.left = nil; self.right = nil; } * public init(_ val: Int, _ left: TreeNode?, _ right: TreeNode?) { * self.val = val * self.left = left * self.right = right * } * } */ class Solution { func invertTr

LeetCodeのEasy問題を解いて勉強するSwift Binary Search編

イメージ
LeetCodeのEasy問題を解いて勉強するSwift Binary Search編 新しくSwiftを触ることになりそうなので ひとまずコードを書いてみることにする。 LeetCodeのEasy問題は比較的解き方を知っている(はず)なので、Python3で書いていた部分をどのような書き方に直すのかを色々思い出しつつ試行錯誤していく。 書いている人のレベル感 Swiftビギナー。基本的な文法すらあやふやなので始めて数日レベルと言っても過言ではない。 LeetCode お題が与えられ、その内容に合わせてコードを書き、提出して合ってるかどうかを確認できる。 問題はソフトウェアエンジニアのコーディング面接で出されたお題をそのまま引用していることがほとんど。 前回 LeetCodeのEasy問題を解いて勉強するSwift Valid Parentheses編 Binary Search Binary Search 与えられた配列(数値が入っている)にtargetが存在する場合はその数値が存在するインデックスを、存在しない場合には -1 を返す関数を書く。 class Solution { func search ( _ nums : [ Int ] , _ target : Int ) - > Int { var left = 0 var right = nums . count - 1 while left <= right { let mid = left + ( right - left ) / 2 if nums [ mid ] == target { return mid } else if nums [ mid ] < target { left = mid + 1 } else { right = mid - 1 } } return - 1

LeetCodeのEasy問題を解いて勉強するSwift Valid Parentheses編

イメージ
LeetCodeのEasy問題を解いて勉強するSwift Valid Parentheses編 新しくSwiftを触ることになりそうなので ひとまずコードを書いてみることにする。 LeetCodeのEasy問題は比較的解き方を知っている(はず)なので、Python3で書いていた部分をどのような書き方に直すのかを色々思い出しつつ試行錯誤していく。 書いている人のレベル感 Swiftビギナー。基本的な文法すらあやふやなので始めて数日レベルと言っても過言ではない。 LeetCode お題が与えられ、その内容に合わせてコードを書き、提出して合ってるかどうかを確認できる。 問題はソフトウェアエンジニアのコーディング面接で出されたお題をそのまま引用していることがほとんど。 前回 LeetCodeのEasy問題を解いて勉強するSwift Valid Palindrome編 次回 LeetCodeのEasy問題を解いて勉強するSwift Binary Search編 Valid Palindrome Valid Parentheses 与えられた文字列の括弧の種類と数がイコールであるかを判定する関数を書く。 class Solution { func isValid ( _ s : String ) - > Bool { var stack : [ Character ] = [ ] for c in s { switch c { case "(" : stack . append ( ")" ) case "{" : stack . append ( "}" ) case "[" : stack . append ( "]" ) default : guard c == stack . popLast ( ) else { return false } }

LeetCodeのEasy問題を解いて勉強するSwift Valid Palindrome編

イメージ
LeetCodeのEasy問題を解いて勉強するSwift Valid Palindrome編 新しくSwiftを触ることになりそうなので ひとまずコードを書いてみることにする。 LeetCodeのEasy問題は比較的解き方を知っている(はず)なので、Python3で書いていた部分をどのような書き方に直すのかを色々思い出しつつ試行錯誤していく。 書いている人のレベル感 Swiftビギナー。基本的な文法すらあやふやなので始めて数日レベルと言っても過言ではない。 LeetCode お題が与えられ、その内容に合わせてコードを書き、提出して合ってるかどうかを確認できる。 問題はソフトウェアエンジニアのコーディング面接で出されたお題をそのまま引用していることがほとんど。 前回 LeetCodeのEasy問題を解いて勉強するSwift Two Sum編 次回 LeetCodeのEasy問題を解いて勉強するSwift Valid Parentheses編 Valid Palindrome Valid Palindrome 与えられた文字列が回文であるかを確認する関数を書く。 いわゆるTwo Pointerで解く。 最初ループ処理をrepeat while文で書いていたけどwhile文でも書けるんだっけ?となって書き直した。 そもそもrepeat while文とwhile文の違いってなんぞや?となったので調査。 repeat while →ループ条件に関わらずループ処理を一回だけ 必ず 実行する『while文』」 while →ループ条件を確認し、 条件に合致した場合にのみ ループ処理が行われる。 class Solution { func isPalindrome ( _ s : String ) - > Bool { if s . isEmpty { return true } let StringArray = Array ( s ) var pointer_1 = 0 var pointer_2 = s . count - 1 // 前からのポインターと後ろからのポイン

LeetCodeのEasy問題を解いて勉強するSwift Two Sum編

イメージ
LeetCodeのEasy問題を解いて勉強するSwift Two Sum編 新しくSwiftを触ることになりそうなので ひとまずコードを書いてみることにする。 LeetCodeのEasy問題は比較的解き方を知っている(はず)なので、Python3で書いていた部分をどのような書き方に直すのかを色々思い出しつつ試行錯誤していく。 書いている人のレベル感 Swiftビギナー。基本的な文法すらあやふやなので始めて数日レベルと言っても過言ではない。 LeetCode お題が与えられ、その内容に合わせてコードを書き、提出して合ってるかどうかを確認できる。 問題はソフトウェアエンジニアのコーディング面接で出されたお題をそのまま引用していることがほとんど。 次回 LeetCodeのEasy問題を解いて勉強するSwift Valid Palindrome編 Two Sum Two Sum LeetCodeを始めた大多数の人が恐らく一番最初に解くであろう問題。 一番簡単な二重for文で書いた場合。 ただし遅い。 class Solution { func twoSum ( _ nums : [ Int ] , _ target : Int ) - > [ Int ] { for i in 0 . . < nums . count { for j in i + 1 . . < nums . count { if nums [ i ] + nums [ j ] == target { return [ i , j ] } } } return [ ] } } 速度を改良した書き方の場合。 class Solution { func twoSum ( _ nums : [ Int ] , _ target : Int ) - > [ Int ] { var seen = [ Int : Int ] ( )

【メモ】Swiftの@State

イメージ
@Stateってなんぞや と言う話。 ただのメモなので基本の当たり前のことについて書いておく。 まあ更新可能な変数を宣言したい時につけとけばそう言うものとして扱ってくれるんだろうなぁ、程度のイメージだった。 ただ、知らなかったのはこの値を更新するたびに body を更新、画面を 再描画 するということ。 Swift初期のこととかよく知らなかったけど、この仕組み自体 Swift5.1 で追加されたものらしい。 そもそも論としてstructが基本的に更新不能と言うことを考えれば何かしらの回避可能な仕組みがあって当たり前だろう、ということになりそうなものだけど新しい事を学ぶ時ってインプットが多くなりすぎて詰め込む方に意識がいってしまいすごく今更なメモになった。 ちなみにひとまず動かしてみた例がこれ。 トグルボタンを用意して状態出力するもの。 ソースは ここ 。

SwiftUIのViewModifierについて

イメージ
初心者向け 開発者定義のViewModifier 初心者向け の記事。 SwiftUIではViewでUIの要素を指定し、ViewModifierで要素のレイアウトを整えていく。 その書き方はそれぞれの要素に対して // // ContentView.swift // Modifier // // Created by kuehar on 2021/07/01. // import SwiftUI struct ContentView : View { var body : some View { Text ( "Hello, world!" ) . padding ( ) } } struct ContentView_Previews : PreviewProvider { static var previews : some View { ContentView ( ) } } プロジェクトを作ったときはこういう形式でコードが生成されるが、このコードの中の .padding() が実際のViewModifer。 Previewで見てみると最初はこんな感じだが、 例えば .padding(bottom) に変えてみると、 少しだけ Hello, World! が上に動いている。非常に分かりづらいが。 こういった形で各要素を修飾することによって要素の内容を変えていく。 開発者定義のViewModifier 同時に、開発者側で定義する再利用可能なViewModifierを作成できる。 開発者でどのビューにも適用できる再利用可能なViewModifierを作成したい場合に用いるもので、いくつかのViewModifierを組み合わせて新しいViewModifierを作成することができる、というもの。 例えば Apple公式のViewModifier のドキュメントでは以下のようなViewModifierを定義し、使用しています。 // // ContentView.swift // Modifier // // Created b

ど素人がYouTube上のSwiftUIの動画を見ながら模写した話

イメージ
SwiftUIマスターに、俺はなる! という冗談は置いておいて。 なんか楽しそうなアニメーションとかやりたいよなぁ〜と思い、YouTubeで SwiftUI Animation で検索したら面白そうなのがあったので見様見真似で模写。 コードは ここ。 何ができるかというとこんな感じのボタンを押した時に以下のようなアニメーションを行うというもの。 すっごい立体的・・・ 特に技術的な記事ではないけど無料でこういうちょっとした遊びを学べるのはいい時代だなぁと思いました。 基本は公式のチュートリアルでさくっと学んであとは無料で真似て描いてこれっていうものを作ってみるという時代が来ているのかも。 これからも楽しく学んでいけるといいなと思いました! (小学生の感想文かな?)

SwiftのCoreDataってなんやねんって話

イメージ
忘れることが多いので 逐一メモしておく。 間違えている場合は親切な方が指摘してくれると思う。 で、コアデータってなんやねんという話。 調べてみたら、 Apple系の製品(WatchOSとかMacOSも含む)アプリ開発ではデバイス単体でオフラインでもアプリのデータを使えるようにしたり、一時的なデータをキャッシュしたりとかするためにコアデータフレームワークなる仕組みでデータを管理してるんだそうな。 それらの特徴としては、 アプリケーションにおけるモデルレイヤにあたる部分 データを溜めて、取り出して、更新して、削除ができる オブジェクトグラフを管理できる 特別な実装をしなくてもUNDO/REDOができる 一時的なデータをキャッシュできる 大きな枠組としてはデータベースではない (一般的にはSQLiteを使う事が多いみたい) 特徴的にはこんな感じっぽい。 SQLiteってデータベースの枠組みに入るんちゃうんかい・・・と思ったけど、バイナリデータとかXMLファイルで管理することもあるらしく、くくりやすくするためにざっくりとまとめたらそうなったみたい。 あまり納得は言っていない。 オブジェクトグラフというのは例えば本があった時にそれに付随するその本の筆者やジャンルなどの付随情報をグラフ構造で管理している、みたいな形式のことらしい。 データベースを使うんだろうなぁと個人的には思っていたので個人的には衝撃。