[iOS] 配列をソート(並び替え)したい | Array, sort, sorted

2019/07/20

こんにちは。きんくまです。

配列のソート(並び替え)があやふやだったので、調べてみました。

sortとsorted

配列には sort と sorted があります。

sort
sortは配列の中身を変更します。

        var intArr = [10, 5, 3]
        intArr.sort()
        print("\(intArr)") // [3, 5, 10]
        
        var strArr = ["b", "c", "a"]
        strArr.sort()
        print("\(strArr)") // ["a", "b", "c"]

sorted
sortedは配列の中身を変更しないで、ソートされた新しい配列を返します

        let intArr = [10, 5, 3]
        let sortedIntArr = intArr.sorted()
        print("\(intArr)") // [10, 5, 3] 元のまま
        print("\(sortedIntArr)") // [3, 5, 10] ソートされてる
        
        let strArr = ["b", "c", "a"]
        let sortedStrArr = strArr.sorted()
        print("\(strArr)") // ["b", "c", "a"] 元のまま
        print("\(sortedStrArr)") // ["a", "b", "c"] ソートされてる

最近の関数型プログラムの流行からすると、元の配列を変更せず変更後のものを返す sorted を使うのが良さそう。

この投稿の続きを読む »

LINEで送る
Pocket

[iOS] Xcode 10.2 / iOS SDK 12.2 | Codableで Dictionary型のキーはキャメルケースに変換されない

2019/06/6

こんにちは。きんくまです。

Swift5はXcode10.2から使用可能で、先日アップデートしました。
それで、Xcode10.2でJSONからオブジェクトに変換するときの挙動がちょっと変わっていたので、共有です。


struct Sample: Codable {
    var keyName1: String?
    var keyName2: [String: String]?
    var keyName3: Child?
    
    struct Child: Codable {
        var chKeyName1: String?
        var chKeyName2: [String: String]?
        var chKeyName3: GrandChild?
    }
    
    struct GrandChild: Codable {
        var gcKeyName1: String?
        var gcKeyName2: [String: String]?
    }
}

        let jsonText = """
{
    "key_name1": "hello1",
    "key_name2": {
        "sub_child1": "hello2",
        "sub_child2": "hello3"
    },
    "key_name3": {
        "ch_key_name1": "hello4",
        "ch_key_name2": {
            "sub_child3": "hello5",
            "sub_child4": "hello6"
        },
        "ch_key_name3": {
            "gc_key_name1": "hello7",
            "gc_key_name2": {
                "sub_child5": "hello8",
                "sub_child6": "hello9"
            }
        }
    }
}
"""

        let decoder = JSONDecoder()
        decoder.keyDecodingStrategy = .convertFromSnakeCase
        let textData = jsonText.data(using: .utf8)!
        do {
            let decodedSample = try decoder.decode(Sample.self, from: textData)

            //Xcode10.1まではこれでいけたのに、Xcode10.2だと空になる
            decodedSample.keyName2["subChild1"] // nil

            //Xcode10.2からはこちら
            decodedSample.keyName2["sub_child1"] // "hello2"

            //同様に辞書部分はキャメルケースでアクセス
            decodedSample.keyName3?.chKeyName3?.gcKeyName2?["sub_child5"]
        } catch let error {
            print("error \(error)")
        }

これについてテストしました。

Child型やGrandChild型といった型を定義したものであれば、JSONのプロパティ名がスネークケースのものが型のキャメルケースプロパティに入ります。(従来のまま)

ネストの状況も2階層、3階層とあってもしっかり変換されました!

しかし!型を定義していない辞書型の [String:String] とかだと、キーはキャメルケースに変換されずにスネークケースのままになります。OH!

しれっと、重要なところ変えてきたよリンゴさん!これで動かないアプリいっぱいあると思うよ!
リリースノートにも書いてなかったよw

参考)
Dictionary keys are no longer converted using keyDecodingStrategy under Xcode 10.2

LINEで送る
Pocket

[iOS] ベースクラスのextensionを、protocolで実装する話

2019/05/29

こんにちは。きんくまです。

Swiftのextensionは大変便利で、いろいろなクラスに対して拡張実装を作ることが可能です。

例えば

extension UIViewController {
    func showAlert(title: String?, message: String?, callback: @escaping () -> Void) {
        let alertController = UIAlertController(title: title,
                                                message: message,
                                                preferredStyle: .alert)
        let okAction = UIAlertAction(title: "OK",
                                     style: .default) { action in
            callback()
        }
        let cancelAction = UIAlertAction(title: "Cancel",
                                         style: .cancel,
                                         handler: nil)
        alertController.addAction(okAction)
        alertController.addAction(cancelAction)
        present(alertController, animated: true, completion: nil)
    }
}

こんな感じに、UIViewControllerに対して、アラートを出すことができるメソッドを定義することができます。

ただ、個人的にはこういう全ての場面で共通で使いそうなクラス(この場合UIViewController)に対して拡張を書くというのが、気になるなーと思いました。どこが気になるかというと、

– クラスを拡張していることが、クラスの定義のところを見るだけだと気づかない
– 使う必要のないクラスにも適用されてしまう

という感じでしょうか。例えば、上のコードだと、アラートを出す必要のないUIViewControllerにも拡張されてしまいます。

この投稿の続きを読む »

LINEで送る
Pocket

[iOS] RxSwiftのmapとflatMapの違い

2019/03/2

こんにちは。きんくまです。

今回はRxSwiftのmapとflatMapの違いについていまいちわかってなかったので、まとめです。

Rxは観測するObserverと、観測されるObservableという大事な概念があります。
で、それと同じくらい大事なのが、流れを作るSequenceと、その中を流れるElementということだと思いました。
これをイメージしておくと、とたんにわかりやすくなりました。

Observableというのは、SequenceでElementを流すやつ。みたいな。

PublishSubject/Single/Observable などは Sequence です。どんなイベントを発行するか決定します。逆にいうと、どのイベントを発行しないかというのもポイントになってきます。

そのイベントにともなって、Elementを流したりします。(completedのときなどelementを流さないイベントもあるのでこんな表現)

この投稿の続きを読む »

LINEで送る
Pocket

[AIR] Adoebe AIRで、AndroidのFileProviderを使ったANEを作りたい

2019/03/2

こんにちは。きんくまです。

もうやっている人もいないと思うので、個人的なメモです。その2

Androidです。Intentで他のアプリに、Uriを連携したいです。

以前は以下のようなことができていました。

File file = new File("path");
Uri myuri = Uri.fromFile(file);

それで、バージョンがあがってセキュリティが厳しくなって、この方法だと他のアプリに連携できなくなっていました。
調べたところ、FileProviderというのを使うといいみたい。

FileProvider | Android Developers

file:// 形式じゃなくて、 content:// 形式で送ります。詳しい実装方法は他にゆずります。

それで、これを使ったANEを作りたかったのだけど、すごくハマってしまい時間がかかってしまいました。

大いなる参考サイト
DigitalStrawberry/ANE-Share: Adobe AIR native extension for sharing text and bitmap content.

このソースをみつつやっていたのですが、細かいところでAndroid Studioのバージョンが上がっていたりして、うまくいきませんでした。
この投稿の続きを読む »

LINEで送る
Pocket

[AIR] iOS11や12でAdoebe AIRでアプリアイコンが表示されない

2019/03/2

こんにちは。きんくまです。

もうやっている人もいないと思うので、個人的なメモです。

AIRをパッケージした後、iOS12のiPadでアプリアイコンが表示されず、デフォルトの指定していない状態になってしまうことがありました。
パッケージの中にiPad用のアイコン画像もあり、application用のxmlにもちゃんとアイコンを指定しているのに表示されません。

解決 Assets.carファイルを追加する

Adobeの公式にしれっと書いてありました。

Note: 1. Starting AIR 28, Assets.car needs to be packaged along with application xml and swf file for the icons to be visible on devices having iOS 11 and above.

なんか iOS11以降は Assets.car ファイルというのを作って、パッケージの中に含める必要があるとのこと。もっと大きく書いてくれてもいいのよ!!

こちらのページのやり方だとXcodeを使って簡単にできるらしいです。
Icons and the Assets.car file

この投稿の続きを読む »

LINEで送る
Pocket

[Android] ファーウェイの端末で I/HwSecImmHelper: mSecurityInputMethodService is null の表示がでたら電話する

2019/02/24

こんにちは。きんくまです。

ちょっと前に開発用端末用に、ファーウェイのP20 Liteというのを買いました。Android 8 です。
HUAWEI P20 lite

それで、ちょっと調べ物があって、Logcatを見ていたのですが、こんなメッセージがあって詳細がわかりませんでした。

I/HwSecImmHelper: mSecurityInputMethodService is null

調べたところ、どうやらこれはファーウェイ端末が独自で出しているものらしい。
パフォーマンスに影響があるという理由で、詳細なエラーメッセージを消しているみたいなんですね。

Huaweiの端末はAndroidアプリのログを握り潰す – ashiato45の日記

mSecurityInputMethodService is null in logcat – Stack Overflow

それで、この状態を解除してちゃんとエラーメッセージを吐かせる設定方法が面白くて、何と電話をかけるというもの。知ったときに、ちょっとウケてしまったw

*#*#2846579#*#*

実際にやってみます。

この投稿の続きを読む »

LINEで送る
Pocket

ページトップへ戻る