投稿者: itkuma

  • Mac mini 購入

       Mac mini 購入

     Mac mini M4Proを購入しま

    した。カスタマイズは初期設定のままです。

    チップ、メモリーのカスタマイズを考えてい

    たのですが、現在Appleの技術の最先端

    の機種ということもあり、今の私のやりたい

    ことを考えると、カスタマイズは必要ないと

    いう結論に至りました。

     今までは2019年のiMacを使ってい

    たのですが、XcodeでSwiftのプレ

    ビューに結構時間がかかり出したのと、

    Apple Intelligenceを使

    ってみたかったので購入に踏み切りました。

     新しいMac miniを使ってみたとこ

    ろ、Xcodeでのプレビューは快適です。

    ストレスなく表示してくれます。

    Intelligenceの方はまだ日本語

    には対応していないようです。言語設定を英

    語にしていないと、有効になりませんでした。

    しかし、ChatGPTを使うことができる

    ので、AIとおしゃべりして楽しんでます。

     まだ使い出したところですが、買ってよか

    ったと思ってます。

  • やる気のスランプ

       やる気のスランプ

     最近プログラミングをさぼってます。もと

    もと切羽詰まらないとやる気が起きないタイ

    プです。学生時代も試験前日にならないと、

    試験勉強をやりませんでした。さすがに大学

    受験の時は周りの雰囲気に押されて、結構長

    いスパンで勉強したことはあります。でも基

    本、これ以上さぼったらダメになると思えな

    いとやる気が起きませんでした。性格のせい

    にしてプログラミングをさぼっているのを今

    正当化しています。去年の今頃は、ITの世

    界で何とか食いつなごうと思い、とりあえず、

    個人サイトを立ち上げたり、何か一つアプリ

    を作ってアップルストアーに上げることを目

    標にしてたんですが、周りに流されて、別の

    仕事で、食いつなぐことになり、やる気のな

    い状態です。やらないからといって誰に文句

    を言われることもないので、さらにやらない

    状態です。一日でも触らないと気持ちが悪く

    なるくらい没頭できるテーマがあればいいの

    ですが、今のテーマはそれほどでもないとい

    うか、できないからといって、どうというこ

    ともないというか、どうも、やる気のスラン

    プです。今までの経験上、こういう時はやる

    気が起きるまで、じっと待つしかないようで

    す。

  • VisionProデモ体験

      VisionProデモ体験

     近視の老眼の場合どうなるんだろうと気に

    なってました。それを知りたくて、Apple

    StoreでVisionProのデモ体験をしてきました。

     最初に近視のメガネを専用の機械で解析し

    てくれました。そして、それに合うZEISS

    Optical Insertsなるレンズを入れてくれてまし

    た。

     仮想ディスプレイは近くにしても遠くにし

    てもはっきり見えました。どうやら老眼の事

    は気にしなくても良いようです。

     音響も素晴らしく、最初に誕生日のお祝い

    の映像で蝋燭を吹き消す場面があるのですが、

    蝋燭を吹き消す息が、顔を通り、耳元を通り

    すぎていく感じがリアルでした。

     また、バスケットボールの3D映像では、

    ボールがこちらに飛んでくる場面で、反射的

    に体が動いてしまいました。

     三十分程度のデモでしたが、とてもワクワ

    クする経験でした。

  • 初めてのアプリ登録

    Apple Developer Program に登録して、1年以上紆余曲折しながら、初めてApp Store Connectにアプリの審査申請をしてみました。Apple Developer Program に登録したての頃は軽い気持ちで取り組んでました。ところが、いろいろ情報を得ていくうちに今までの知識ではとても間に合わないことに気づき、休日を利用し基本的なところから、まず学習していきました。そのかいあってか簡単なアプリを作ることができたので、ここは試しにアプリの登録をしようとこれまた軽い気持ちで、審査申請に挑戦しました。まずアプリをどうやって審査申請のまな板にのせるかがわからず、ネットを調べたら、XCodeのメニューproduct の archiveでできるとのこと、さっそくやってみました。そして、登録申請のボタンがあるのでとりあえず、クリックすると、メッセージの山です。登録上必要事項が記入されていないと、メッセージが出て、審査申請が完了しません。何度もメッセージに従って必要事項を記入して、根負けしそうになりながらも、何度も審査申請をクリックすると、やっと、審査中になりました。そして、2日目に配信準備完了になりました。同時に何通か来ていたメールに、配信への手順の記載があり、それに従い必要項目を設定し配信できました。AppStoreでの表示はその翌日に可能となりました。

    申請にはプライバシポリシーの保存先URLと、サポートページのURLを記載する必要がありました。このサイトの一部を使用することで対応できました。このサイトはそんなことは全く想定しておらず勢いで作成していたのですが、この時ばかりはこのサイトを運営していてよかった思いました。

  • SwiftData @Modelを使ってList項目の追加・移動・削除を実装してみました

    SwiftDataの@Modelを使って、Listの項目を移動させる処理を作ってみました。@Modelはクラスに適用することで、アプリを終了させてもプロパティの値を保持させることができます。ただしアプリを削除したらプロパティの値は消滅します。

    まず、@Modelを適用させるクラスです。

    import Foundation
    import SwiftData
    
    @Model
    final class Item: Identifiable {
        var name: String
        //チェックボックス表示切り替え用
        var check: Bool
        //移動処理時にソートをかける対象
        var sortNumber: Int
        //移動処理をかけるときにIdentifiableプロトコルを準拠させるのに必要
        var id = UUID()
            
        init(name: String, sortNumber: Int) {
            self.name = name
            self.check = false
            self.sortNumber = sortNumber
        }
    }

    Itemの配列をリストとして表示し項目の追加、移動、削除の処理を可能にしたViewがこちらです。

    import SwiftUI
    import SwiftData
    
    struct ItemListView: View {
        //@Model class Item を modelContextとしてしようできるようにします
        //これでmodelContextの insert delete が利用できます
        @Environment(\.modelContext) var modelContext
        //Listのエディットモードを切り替える変数 editModeを設定
        @Environment(\.editMode) var editMode
        //ItemのsortNumberプロパティを並び替えの対象としてItemの配列をnumbersとして設定
        @Query(sort: \Item.sortNumber) private var numbers: [Item]
        @State var shoppingItem: String = ""
        @State var modeName: String = "追加削除モード開始"
    
        var body: some View {
            VStack {
                if editMode?.wrappedValue.isEditing == true {
                    HStack{
                        //買い物リストのアプリにしているので↓
                        TextField("ここに買い物するものを入力してください", text: $shoppingItem)
                            .font(.system(size: 30))
                            .background(Color.yellow)
                        Button{
                            let i = numbers.count
                            modelContext.insert(Item(name: shoppingItem, sortNumber: i))
                            shoppingItem = ""
                        } label: {
                            Text("追加")
                                .font(.system(size: 24))
                        }
                    }
                    .padding()
                }
                //[Item]のnumbersをListで表示
                List {
                    ForEach(numbers) { number in
                        HStack {
                            //チェックボックスの表示を切り替えると表示文字の大きさと色を変更
                            if number.check == false {
                                Text(number.name)
                                    .font(.system(size: 24, weight: .bold, design: .rounded))
                                    .foregroundColor(.black)
                            } else {
                                Text(number.name)
                                    .font(.system(size: 18))
                                    .foregroundColor(.gray)
                            }
                            Spacer()
                            //チェックボックスの表示を切り替え
                            if number.check == false {
                                Image(systemName: "square")
                                    .scaledToFill()
                                    .onTapGesture {
                                        number.check = true
                                    }
                            } else {
                                Image(systemName: "checkmark.square")
                                    .scaledToFill()
                                    .onTapGesture {
                                        number.check = false
                                    }
                            }
                        }
                    }
                    //移動時の処理
                    .onMove{ fromOffSet, newOffset in
                        var fromIndex: Int = 0
                        
                        //fromOffSetの配列オブジェクトから並び替え用の数値を取得
                        //これが移動対象の並び替え用の数値
                        for itm in fromOffSet {
                            let obj = numbers[itm]
                            fromIndex = obj.sortNumber
                        }
                        
                        var toIndex = 0
                        
                        if newOffset < numbers.count - 1 {
                            toIndex = numbers[newOffset].sortNumber
                        } else {
                            toIndex = numbers[numbers.count - 1].sortNumber + 1
                        }
                        
                        //移動対象と移動先の関係で条件付けし、移動後の並び替え用数値を変化させます
                        //これにより移動処理後に項目の並び替えが行えます
                        if fromIndex > toIndex {
                            numbers[fromIndex].sortNumber = toIndex
                            var toi = 0
                            if toIndex > 1 {
                                toi = toIndex
                            }
                            for i in toi..<fromIndex {
                                numbers[i].sortNumber += 1
                            }
                        } else if fromIndex < toIndex {
                            numbers[fromIndex].sortNumber = toIndex
                            let fromi = fromIndex
                            for i in fromi..<toIndex {
                                numbers[i].sortNumber -= 1
                            }
                        }
                    }
                    //削除時の処理
                    .onDelete{ indexSet in
                        //
                        for item in indexSet {
                            let obj = numbers[item]
                            modelContext.delete(obj)
                            //削除処理後並び替え用の数値を変化させます
                            //これにより移動処理後に項目の並び替えが行えます
                            //項目追加時に配列の個数を元に並び替え用数値を設定しているのでここで全体の数値を整理しています
                            if obj.sortNumber < numbers.count - 1 {
                                for i in obj.sortNumber..<numbers.count {
                                    numbers[i].sortNumber -= 1
                                }
                            }
                        }
                    }
                    .listRowBackground(Color.yellow)
                }
                .scrollContentBackground(.hidden)
                .background(.clear)
    
                Button {
    
                    if editMode?.wrappedValue.isEditing == true {
                        editMode?.wrappedValue = .inactive
                        modeName = "追加削除モード開始"
                    } else {
                        editMode?.wrappedValue = .active
                        modeName = "追加削除モード終わり"
                    }
    
                }label: {
                    Text(modeName)
                        .padding()
                        .font(.system(size: 24))
                        .foregroundColor(.black)
                        .background(Color.green)
                        .cornerRadius(10)
                }
            }
            .padding()
        }
    }
    
  • TestFlightアプリ登録App Reviewに関する情報で電話番号がはじかれる

    TestFlightアプリ登録時 App Reviewに関する情報の電話番号の入力で0から始まる電話番号を入れたら、無効扱いされました。国際電話番号表記にしないといけなかったらしく、はじめの0を日本の国際電話番号+81 に変えたらすんなり受け入れたもらえました。改めて、グローバル感につつかれた感じです。

  • XCodeアプリarchiveでiconのエラー

    簡単なアプリができたので、試しにTestFlightに登録してみようと、XCodeでarchiveをかけて登録しようとしたら、iconの透過ができないかアルファを含んでるとかなんとかで登録できませんでした。結局ファイル書き出し時にPNG形式にして、アルファのチェックを外した物をアイコンにしたらすんなり通りました。assetsに登録時に教えてほしいけど、Apple Developer Programに登録してなくてもアプリを作れるから、その辺はルーズにしてあるのかも・・・。以後気を付けます。

  • 逃げる

       逃げる

     逃げるということになぜか、恥ずかしいと

    か、卑怯というような、イメージを植え付け

    られている気がします。

     逃げるという言葉の意味を調べてみると、

    危険や煩わしいことから積極的に遠ざかると

    か、追手の力の及ばないところに身を置くと

    か、競技においては首位を行くものが後続す

    るものに追いつかれないで勝つといった意味

    でした。恥ずかしさを感じたり、卑怯なこと

    をしているイメージはなさそうです。どこで

    そんなイメージを植え付けられたんでしょう。

    私が小さい頃のテレビの中の人が時々

    「卑怯者、逃げるな!」

    みたいなことを言っていたのを思い出します。

    どうやら、逃がした側の感情のようです。そ

    こから恥ずかしいという感情も派生したので

    しょうか。どちらにしても逃げる側がその行

    為に負の感情を抱く必要はみじんもなさそう

    です。逃げた先で安心な暮らしができれば、

    逃げきっての勝ちといったところでしょうか。

  • SwiftUIの@Observableと@Environmentについて調べてみました

    SwiftUIの@Observableをクラスに適用すると、そのクラスを@EnvironmentでViewに導入すると、そのクラスのプロパティに変更を加えた時その変更を随時Viewに適用してくれます。

    下記コードはTestObservableクラスに@Observableを適用し、ContentViewに@Environmentでそのクラスを導入したものです。

    旧姓、新姓のボタンをクリックすると、クラスのnameプロパティを変化させます。その変化に対応しクラスのnameプロパティをセットしたTextの表示が変化します。

    PreviewもViewにenvironmentでクラスを導入することで、Previewも変化します。

    import SwiftUI
    
    struct ContentView: View {
        @Environment(TestObservable.self) var testObservable
        
        var body: some View {
            Text(testObservable.name)
            Button {
                testObservable.changeName(name: "旧姓")
            } label: {
                Text("旧姓")
            }
            Button {
                testObservable.refreshName()
            } label: {
                Text("新姓")
            }
        }
    }
    
    @Observable
    class TestObservable {
        var name: String
        
        init() {
            self.name = "新姓"
        }
        
        func refreshName() {
            self.name = "新姓"
        }
        
        func changeName(name: String) {
            self.name = name
        }
    }
    
    #Preview {
        ContentView()
            .environment(TestObservable())
    }
    

    @mainからの呼び出しは下記の感じです。

    import SwiftUI
    
    @main
    struct SwiftUILearnApp: App {
        var body: some Scene {
            WindowGroup {
                ContentView()
                    .environment(TestObservable())
            }
        }
    }
    

  • 暑さ寒さも彼岸まで

       暑さ寒さも彼岸まで

     2024年の夏は暑かった。今までにない

    というか、年齢のせいかもしれませんが、暑

    くて、陽の出ている時間にサックスを吹きに

    行く気がしませんでした。

     9月になっても暑い日が続き、彼岸過ぎて

    も暑いのではと思っていると、彼岸前の雨で

    急に気温が下がり、お彼岸には日陰で風にあ

    たると心地よく感じられるようになりました。

    「暑さ寒さも彼岸まで。」

    よく使われる言葉ですが、この時はほんとに

    実感しました。というよりなんだかありがた

    みさえ感じました。涼しくなったのは、言葉

    のおかげではないのですが、昔からある言葉

    の情景が今もまだあることへの感謝なのかも

    しれません。