ObjecTips

Swift & Objective-C で iOS とか macOS とか

Core Data Code Generation の Objective-C と Swift の違い

環境 Xcode 10.0

Core Data Code Generation

Code Generation は Xcode が Core Data のモデルクラスの基本実装を自動で行ってくれる機能で <ProductName>.build/Debug-iphonesimulator/<ProductName>.build/DerivedSources/CoreDataGenerated/<FileName> の中にファイルが自動で生成される。

FileName は .xcdatamodeld のファイル名

Objective-C + Code Generation

Objective-C の場合以下の様な4ファイルが生成される。
(Model は .xcdatamodeld で設定したエンティティ名、もしくはクラス指定をしていればクラス名が入る)

Model+CoreDataClass.h

#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>

NS_ASSUME_NONNULL_BEGIN

@interface Model : NSManagedObject

@end

NS_ASSUME_NONNULL_END

#import "Model+CoreDataProperties.h"

Model+CoreDataClass.m

#import "Model+CoreDataClass.h"

@implementation Model

@end

Model+CoreDataProperties.h

#import "Model+CoreDataClass.h"


NS_ASSUME_NONNULL_BEGIN

@interface Model (CoreDataProperties)

+ (NSFetchRequest<Model *> *)fetchRequest;

@property (nullable, nonatomic, copy) NSDate *creationDate;
@property (nullable, nonatomic, copy) NSDate *modificationDate;

@end

NS_ASSUME_NONNULL_END

Model+CoreDataProperties.m

#import "Model+CoreDataProperties.h"

@implementation Model (CoreDataProperties)

+ (NSFetchRequest< Model *> *)fetchRequest {
    return [NSFetchRequest fetchRequestWithEntityName:@"Model"];
}

@dynamic creationDate;
@dynamic modificationDate;

@end
Swift + Code Generation

Swift の場合以下の2ファイルが生成される。
Model+CoreDataClass.swift

import Foundation
import CoreData

@objc(Model)
public class Model: NSManagedObject {

}

Model+CoreDataProperties.swift

import Foundation
import CoreData


extension Model {

    @nonobjc public class func fetchRequest() -> NSFetchRequest<Model> {
        return NSFetchRequest<Model>(entityName: "Model")
    }

    @NSManaged public var creationDate: Date?
    @NSManaged public var modificationDate: Date?

}

これらのソースが自動で生成され利用する事が出来る。

Objective-C + Code Generation 利用編

Objective-C で Code Generation した場合は追加で以下の2つのファイルも生成され、利用にはこれを import する必要がある。

FileName+CoreDataModel.h

#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>

#import "Model+CoreDataClass.h"

FileName+CoreDataModel.m

#import "FileName+CoreDataModel.h"

Objective-C で利用するにはクラスのヘッダか実装部に import する

#import "ProductName+CoreDataModel.h"

Swift から利用するには Objective-C to Swift の橋渡しとして ProductName-Bridging-Header.h に import する

#import "ProductName+CoreDataModel.h"

*1

Swift + Code Generation 利用編

Swift で Code Generation した場合は追加で以下のファイルが作成されるが、それぞれのクラスのスコープがデフォルトの internal になっているため Objective-C と比べてソースの中身は特に何も実装されていない。

FileName-CoreDataModel.swift

import Foundation
import CoreData

Swift で Code Generation して Swift で使う場合、プロジェクト上にはヘッダもクラス定義も存在しない(見えていない)がクラスを呼び出して使用する事が出来る状態になる。

Objective-C から利用するには Swift to Objective-C の橋渡しとして ヘッダか実装部に以下を import する

#import "ProductName-Swift.h"

*2

*1:Bridging-Header は正確にはビルド設定の Objective-C Bridging Header の値

*2:正確にはビルド設定の Objective-C Generated Interface Header Name の値でデフォルト値は $(SWIFT_MODULE_NAME)-Swift.h