元柔道整復師エンジニアBlog

- 元柔道整復師エンジニアBlog -

『 エンジニアをリングする。』

【Swift】Swift3から日付比較(Date)に演算子が扱えるみたいだった

Swift3で日付比較したい場面に出くわして、

いつものようにDateのcompareあたりを使おうとしてたら、
いつものようにNSComparisonResult(とくにorderedAscendingorderedDescending)でどちらがa < b、a < bとかがわからなくなって確認してたら....

とある記事で、
日付の比較に比較演算子が使えるのを今更しったわけです...
それもSwift3かららしく.....今更ながらお恥ずかしい😓

ってなわけで、さっそく使ってみる。

やること

  • 簡単な3つの日付を配列datesに加えて、それを降順で並び替える。
let calendar = Calendar.current
let date1 = calendar.date(from: DateComponents(year: 2017))!
let date2 = calendar.date(from: DateComponents(year: 2018))!
let date3 = calendar.date(from: DateComponents(year: 2019))!

var dates = [date1, date2, date3]

print(dates)
// [2016-12-31 15:00:00 +0000, 2017-12-31 15:00:00 +0000, 2018-12-31 15:00:00 +0000]

これまで(Swift2以前)

orderedAscendingorderedDescendingとで、
一見、どちらがa > bで、どちらがa < bなのかかがわかりづらい。

dates.sort { (d1, d2) -> Bool in
    return d1.compare(d2) == .orderedDescending 
}

print(dates)
// [2018-12-31 15:00:00 +0000, 2017-12-31 15:00:00 +0000, 2016-12-31 15:00:00 +0000]

Swift3以降

比較演算子が扱えることによって直感的でわかりやすくなった。

dates.sort { (d1, d2) -> Bool in
    return d1 > d2
}

print(dates)
// [2018-12-31 15:00:00 +0000, 2017-12-31 15:00:00 +0000, 2016-12-31 15:00:00 +0000]

参考

CoreDataのSubclass/Propertiesクラスを生成したらMultiple commands produce...によりビルトが通らなくなった

オフライン時のデータ保持のために、CoreDataを使いう機会がありそのときにつまずいたことを書いていく。

もともとCoreDataモデルをいくつか作成していて、
これまで通りに今回もCoreDataモデル(User)を新たに追加するために

  • CoreDataModel.xcdatamodelを作成する
  • CoreDataModelにEntityを追加する
  • 管理対象のオブジェクトサブクラス+CoreDataClassおよびプロパティファイル+CoreDataPropertiesを作成する

の手順で生成したあとにビルドを通してみると

:-1: Multiple commands produce '/Users/ユーザ名/Library/Developer/Xcode/DerivedData/***/Build/Intermediates.noindex/***.build/Debug-iphoneos/***.build/Objects-normal/arm64/User+CoreDataProperties.o':
1) Target 'Scheme名' (project 'App名') has compile command for Swift source files
2) Target 'Scheme名' (project 'App名') has compile command for Swift source files

:-1: Multiple commands produce '/Users/ユーザ名/Library/Developer/Xcode/DerivedData/***/Build/Intermediates.noindex/***.build/Debug-iphoneos/***.build/Objects-normal/arm64/User+CoreDataClass.o':
1) Target 'Scheme名' (project 'App名') has compile command for Swift source files
2) Target 'Scheme名' (project 'App名') has compile command for Swift source files

というエラーが発生した。

どちらもNSManagedObjectサブクラスを生成したときのUser+CoreDataPropertiesUser+CoreDataClassが影響してるみたい...

しかし、これまで通り作業手順は変えてもいないのに急になぜ!?

....と思いつつ調べてみた

※以降からは、 CoreDataから生成した管理対象のオブジェクトサブクラス〇〇+CoreDataClassとプロパティファイル〇〇+CoreDataPropertiesをまとめてNSManagedObjectと呼んでいます。

原因

どうやらXcode8以降、CoreDataからNSManagedObjectを生成する際のコード生成オプション(Codegen)設定が追加されたみたいで

これまでのようなCoreDataのEntity作成後に
手動でEditor > Create NSManagedObject Subclass...をしなくても、デフォルト状態でNSManagedObjectを自動生成してくれる仕組みになったらしい。

そこでCodegenの設定を見てみると、 f:id:CHU-BURA:20190518141834p:plain

Codegenプロパティ値は、デフォルトであるクラス定義Class Definitionとなっていた。

このClass Definitionは公式によると

Choose Class Definition If You Won't Need to Edit the Generated Logic or Properties
Choose this option when you don’t need to edit the properties or functionality of the managed object subclass and properties files that Core Data generates for you.
The generated source code doesn’t appear in your project’s source list. Xcode produces the class and properties files as part of the build process and places them in your project’s build directory.
These files regenerate whenever the related entity changes in the data model.


生成されたロジックやプロパティを編集する必要がない場合は、クラス定義(Class Definition)を選択してください。
Core Dataが生成する管理対象オブジェクトサブクラスおよびプロパティファイルのプロパティや機能を編集する必要がない場合は、このオプションを選択してください。
生成されたソースコードは、プロジェクトのソースリストには表示されません。 Xcodeは、ビルドプロセスの一部としてクラスファイルとプロパティファイルを作成し、それらをプロジェクトのビルドディレクトリに配置します。
これらのファイルは、関連するエンティティがデータモデル内で変更されるたびに再生成されます。
Generating Code | Apple Developer Documentation

要するにプロジェクト内のソースとして見えていないだけで、Class Definitionを設定した時点でNSManagedObjectが内部的に生成されていた。

そしてNSManagedObjectが生成されているにもかかわらず、
再度、手動でEditor > Create NSManagedObject Subclass...したことにより同一名のNSManagedObjectが重複してしまいコンパイルエラーが発生した。

これまで生成したCoreDataのCodegenプロパティを見てみると
Class Definitionではなく、Manula/Noneの設定がされていて、なんらかの影響でデフォルトの設定になってしまってたようだ...

解決

現在のClass Definitionを設定した状態で、そのあとに手動追加していたEditor > Create NSManagedObject Subclass...をしなければ簡単に解決はする....

しかし今回の場合は、生成したNSManagedObjectにメンバ変数やメソッドを追加したい。
→ Core Dataが生成する管理対象オブジェクトサブクラスおよびプロパティファイルのプロパティや機能を編集する必要がある。

そうなると現在の設定Class DefinitionでNSManagedObjectを生成した場合は、生成されたNSManagedObjectのロジックやプロパティを編集することができない。

そこでCodegenプロパティをManula/Noneにすることで、

  • NSManagedObjectの自動生成を無効にして
    → 同一名のNSManagedObjectによる重複エラーの回避
  • 手動Editor > Create NSManagedObject Subclass...でNSManagedObjectを生成できる。
    → NSManagedObjectのロジックやプロパティの編集が可能

f:id:CHU-BURA:20190518184359p:plain

Choose Manual/None to Edit Properties and Logic in the Managed Object Subclass
Choose this option to edit the properties in your managed object subclass, for example, to alter access modifiers, and to add additional convenience methods or business logic.
With Manual/None, Core Data doesn’t generate files to support your class. You create and maintain your class, including its properties, manually. Core Data then locates these files using the values you supply in the class name and module fields.
To generate the class and properties files initially:

  1. Choose Editor > Create NSManagedObject Subclass from the menu at the top of the screen.
  2. Select your data model, then the appropriate entity, and choose where to save the files. Xcode places both a class and a properties file into your project.

You can now see and edit both the class and properties files in your project source list.


管理対象サブクラスのプロパティとロジックを編集するには、Manula/None を選択します。
このオプションを選択すると、たとえば、アクセス修飾子を変更したり、便利なメソッドやビジネスロジックを追加したりするために、管理オブジェクトサブクラスのプロパティを編集できます。
Manual / Noneの場合、Core Dataはクラスをサポートするためのファイルを生成しません。手動でクラスを作成し、そのプロパティも含めて管理します。その後、Core Dataは、クラス名とモジュールフィールドに指定した値を使用してこれらのファイルを見つけます。
クラスファイルとプロパティファイルを最初に生成するには

  1. 画面上部のメニューから「エディタ」>「NSManagedObjectサブクラスの作成」を選択します。
  2. データモデルを選択してから適切なエンティティを選択し、ファイルの保存場所を選択します。Xcodeはクラスとプロパティファイルの両方をプロジェクトに配置します。

これで、プロジェクトソースリスト内のクラスファイルとプロパティファイルの両方を表示して編集できます。
Generating Code | Apple Developer Documentation

参考

〇〇国家試験合格率100%にダマされなで!合格率の裏側とその実態について

どうも、元柔道整復師エンジニア のん です。

私は国家資格である柔道整復師を目指すべく、柔道整復師国家試験を受験した1人でもあります。

そこで今回は、私自身が入学後に気づいた
『国家試験合格率100%の裏側とその実態』について、実際に受験した柔道整復師国家試験を例に挙げて紹介していきます。

まず、はじめに

将来、国家資格取得を必要とする職業に就きたい場合は、国家試験合格が必須になるのではないか思います。

そこでまず多くの方は、国家試験合格の第一歩にむけて、合格率の高い学校または大学を探して、志望しようと考えるではないでしょうか?

もちろんそれだけの理由ではないかもしれませんが、私の場合は少なからずその考えを持った上で進学を決意しました。

そして進学先を決める上で「国家試験合格率〇〇%」といった過去の実績は重要なポイントの一つでした。

入学後、私は無事に国家試験合格率が高い学校に進学できたましたが
いざ入学してフタを開けてみると、入学前の進学先選択で重要視していた国家試験合格率というものが如何にして高い確率で保たれているかを知ることになりました。

国家試験合格率100%の定義について

当たり前ですが、国家試験合格率は

  • 受験者数
  • 受験合格者数

が一致する(受験者数=受験合格者数)ことが国家試験合格率100%の定義です。

国家試験合格率100%の裏側とその実態について

ただ先ほどの国家試験合格率100%は、
あくまでも『その年における国家試験の受験資格を得ることのできた人だけが、誰一人として落ちることなく全員合格できた』ということです。

「え、なに言ってるの❓当たり前じゃん❗」っとなるかもしれませんが....

私がここで言いたいのは、
『入学者全員がエスカレーターのように進級したとしても、必ずその全員が国家試験の受験資格を得ることができる訳ではない』ということです。

この理由として、パッと思いつくのは単位不足やその他事情などにより進級することできない、いわゆる留年ではないですか?

ただこれに関しては、ごく当たり前のことで国家試験合格率100%には全く関係ないものです。

しかし、もう1つの理由として考えられるのが、
学力によって国家試験の受験資格すら得ることが出来ないという場合があります。

これは留年とは別に、学校側が国家試験対策に向けて定期的に学校独自の学力試験国家試験対策模試試験などの成績によって、ある一定以上の成績者ではないと受験資格を与えないという考え方です。

もちろん、私が進学した学校もこれに当たり、
「この人の成績では、国家試験を受験しても合格までは至らないだろう」と判断された場合は、国家試験を受験することすら認められません。

しかし、すべての学校がこれに該当するわけではないと思いますが、
とくに学校のHPやパンフレット等で「国家試験合格率〇〇%」といった合格率が高いことを強く推している学校に関しては、このケースに当たることが多いのではないかと思います。

なぜなら、合格率の高い学校はその「合格率の高さ」をキャッチコピーにして学校の注目度・評判を上げています。
悪い言い方をすれば、「合格確率が高い」というのは学校側にとって入学者が増えることに繋がり、同じ分野のライバル学校よりも設けることができる一つの手段になります。

ただこれは学校側からしてみたら、ごく当たり前の社会的ビジネスの手段なんだなと感じます。

最後に

ここまであまりいい事を言っていませんが、 国家試験合格率が高いということは、その学校が国家試験合格に向けた教育に力を入れているという点でもあります。

結果的に、国家資格を有する職業に就きたいのであれば国家試験に合格しないと始まりません。

ここでは、国家試験合格率100%の学校に入学したからといって、
必ずしも全員が合格できるものではないということを少しでもお伝えできていれば幸いです。

そして、これから進学先を決めようと思っている方は、
国家試験合格率だけに目を向けるのではなく、その他の点も踏まえて進学先選択をしていただけたらなと思います。

【Swift】@IBActionのsender(Any型)からUIButtonの重複タップを防止する。

目的

  • StoryBoard上のあるUIButtonに接続された@IBActionsender(Any型)から重複タップを防止したい。
  • @IBActionのみ接続されたUIButtonの重複タップを防止したい。

前提条件

  1. StroryBoard側には、対象のUIButtonが配置されている。
  2. コード側では、1.のUIButtonが@IBActiononClickButton(sender: Any)にのみ接続されている。
  3. StoryBoard上への変更は加えない。
class ViewController: UIViewController {
    
    // UIButton押下時の処理
    @IBAction func onClickBtn(_ sender: Any) {
        
        // ここで重複タップを防止させたい
    }

}

方法

  • @IBActionのsenderからUIButton属性を取得する。
    →この場合、senderはAny型のためUIBUttonへキャストする。

  • UIButton属性を取得後、Enabledステータスをfalseに変更する。
    →UIButtonを非活性にする。

  • UIButton押下時に、Enabledステータスをtrueに戻す。
    →UIButtonを活性にもどす。

class ViewController: UIViewController {
    
    // UIButton押下時の処理
    @IBAction func onClickBtn(_ sender: Any) {
        
        // UIButtonを非活性にする
        let targetButton = sender as! UIButton
        targetButton.isEnabled = false
        
        // 何らかの処理(アニメーションなど)
        ・
        ・
        ・
        
        // メイン処理後に、UIButtonを活性に戻す
        targetButton.isEnabled = true
    }

}

〇〇整骨院と〇〇接骨院の違いとは?△△整骨院と△△整体院の違いとは?

どうも、元柔道整復師エンジニア のん です。

最近では、昔と比べて〇〇整骨院や〇〇接骨院をよく見かけるようになりました。
そこで今回は、その整骨院接骨院の違い整骨院と整体院の違いの2つについて書きました。

整骨院接骨院の違い

さっそく、その 整骨院接骨院の違い ですが...
名称が違うだけで、施術(業務)に関する違いは全くありません、同一です⭕

どちらも国家資格を取得した柔道整復師が働いており、保険適用となります!

整骨院と整体院の違い

注意していただきたいのが、この整骨院と整体院の違いについてです。

たったこのという1文字の違いですが、
整骨院と整体院は違います、別物と考えてください❌
そして、整体院は保険適用外です!

整骨院は、先ほど簡単に説明した通り
国家資格を有している柔道整復師が、患者さんに直接施術をします。

しかしそれとは違って、
整体院は、民間資格を有している整体師が治療を目的として行っています。

似ているようで違うので、注意してください。

まとめ

名称 特徴 保険適用
○○接骨院 国家資格を有している柔道整復師 あり
○○整骨院 国家資格を有している柔道整復師 あり
○○整体院 民間資格を有している整体師 なし