Last active
July 7, 2016 23:02
-
-
Save gitbricho/9f3b07e50144c93fefab48c403807665 to your computer and use it in GitHub Desktop.
Core Data
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
... | |
// ## アプリ・ドキュメントDIR | |
// Core Data 保存ファイルを保存するために使用. | |
lazy var applicationDocumentsDirectory: Foundation.URL = { | |
// ファイルマネージャを使ってアプリ・サポート・ディレクトリを取得 | |
let urls = FileManager.default().urlsForDirectory( | |
.applicationSupportDirectory, inDomains: .userDomainMask) | |
let appSupportURL = urls[urls.count - 1] | |
// 取得ディレクトリ + "/CoreDataDemo_Data" を返す | |
print("アプリ・ドキュメントDIR: \(appSupportURL)") | |
return try! appSupportURL.appendingPathComponent("CoreDataDemo_Data") | |
}() | |
... |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
... | |
// ##管理オブジェクトモデル (非オプショナル) | |
lazy var managedObjectModel: NSManagedObjectModel = { | |
// "DataModel.momd" ファイルの URLを取得 | |
// オプショナルではないので、ロードできない場合はエラー | |
// コンパイル後:App.xcdatamodeld --> App.momd | |
let modelURL = Bundle.main().urlForResource("App", withExtension: "momd")! | |
// 指定 URL の管理オブジェクトモデルを返す | |
return NSManagedObjectModel(contentsOf: modelURL)! | |
}() | |
... |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
... | |
// ## 永続ストアコーディネータ (オプショナル). | |
// (必要なら、保存ディレクトリを作成) | |
lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = { | |
let fileManager = FileManager.default() | |
var failError: NSError? = nil | |
var shouldFail = false | |
var failureReason = "保存データの生成またはロードエラー." | |
// 保存ディレクトリが存在するか確認. | |
do { | |
// コンテンツ取得 | |
let properties = try self.applicationDocumentsDirectory.resourceValues(forKeys: [URLResourceKey.isDirectoryKey]) | |
if !properties.isDirectory! { | |
// エラー:指定パスのコンテンツは存在するがフォルダではない | |
failureReason = "データ保存用フォルダ: \(self.applicationDocumentsDirectory.path) はフォルダではない." | |
shouldFail = true | |
} | |
} catch { | |
// コンテンツが存在しない | |
let nserror = error as NSError | |
if nserror.code == NSFileReadNoSuchFileError { | |
do { | |
// 保存ディレクトリを作成する | |
try fileManager.createDirectory(atPath: self.applicationDocumentsDirectory.path!, | |
withIntermediateDirectories: true, attributes: nil) | |
} catch { | |
failError = nserror | |
} | |
} else { | |
failError = nserror | |
} | |
} | |
// ストアコーディネータ(オプショナル)を作成 | |
var coordinator: NSPersistentStoreCoordinator? = nil | |
if failError == nil { | |
// 保存ディレクトリの確認(または作成)に成功したらコーディネータを生成 | |
coordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel) | |
// アプリ・ドキュメントDIR + "/CoreDataDemo.storedata" の url を取得 | |
let url = try! self.applicationDocumentsDirectory.appendingPathComponent("CoreDataDemo.storedata") | |
do { | |
// コーディネータに取得 url の永続ストアファイルを追加 | |
try coordinator!.addPersistentStore(ofType: NSXMLStoreType, configurationName: nil, at: url, options: nil) | |
} catch { | |
// エラー処理をここに記述. | |
/* | |
ここで扱う典型的なエラー: | |
* 永続ストアへのアクセス不可(原因:デバイスロック時のパーミッション|データプロテクト) | |
* デバイスの容量不足 | |
* ストアが現モデルバージョンにマイグレートできなかった | |
実際の問題が何か判定するためにメッセージを調べる。 | |
*/ | |
failError = error as NSError | |
} | |
} | |
if shouldFail || (failError != nil) { | |
// Report any error we got. | |
if let error = failError { | |
NSApplication.shared().presentError(error) | |
fatalError("Unresolved error: \(error), \(error.userInfo)") | |
} | |
fatalError("Unsresolved error: \(failureReason)") | |
} else { | |
// コーディネータを返す | |
return coordinator! | |
} | |
}() | |
... |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
... | |
// ##管理オブジェクトコンテキスト (オプショナル). | |
// すでに永続ストアコーディネータと結合されている. | |
lazy var managedObjectContext: NSManagedObjectContext = { | |
// 永続ストアコーディネータを取得(オプショナル) | |
let coordinator = self.persistentStoreCoordinator | |
// 管理オブジェクトコンテキストを生成 | |
var managedObjectContext = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType) | |
// コンテキストに永続ストアコーディネータを設定 | |
managedObjectContext.persistentStoreCoordinator = coordinator | |
return managedObjectContext | |
}() | |
... |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
... | |
// アプリ終了前に呼ばれる. | |
// アプリの管理オブジェクト・コンテキストでの変更を保存. | |
func applicationShouldTerminate(_ sender: NSApplication) -> NSApplicationTerminateReply { | |
if !managedObjectContext.commitEditing() { | |
NSLog("\(NSStringFromClass(self.dynamicType)) 終了のための編集コミットに失敗.") | |
return .terminateCancel | |
} | |
if !managedObjectContext.hasChanges { | |
return .terminateNow | |
} | |
do { | |
try managedObjectContext.save() | |
} catch { | |
let nserror = error as NSError | |
// ここにアプリ特有のリカバリ処理を記述: | |
... | |
let answer = alert.runModal() | |
if answer == NSAlertSecondButtonReturn { | |
return .terminateCancel | |
} | |
} | |
// If we got here, it is time to quit. | |
return .terminateNow | |
} | |
... |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
... | |
// アプリ終了前に呼ばれる. | |
// アプリの管理オブジェクト・コンテキストでの変更を保存. | |
func applicationShouldTerminate(_ sender: NSApplication) -> NSApplicationTerminateReply { | |
//管理オブジェクトを変更 | |
// ここでは新しい社員を作成 | |
let entity = NSEntityDescription.entity(forEntityName: "Syain", in: managedObjectContext) | |
let syain: SyainMO = SyainMO(entity: entity!, insertInto: managedObjectContext) | |
syain.simei = "山田太郎" | |
syain.nyusyaBi = "2013/04/01" | |
syain.seinenGappi = "1982/11/23" | |
if !managedObjectContext.commitEditing() { | |
... | |
} | |
... | |
do { | |
// 変更を保存 | |
try managedObjectContext.save() | |
//変更が保存されたことの確認とデータ取得機能のテスト | |
let fetchReq: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest(entityName: "Syain") | |
let results = try! managedObjectContext.fetch(fetchReq) as! [SyainMO] | |
for syain in results { | |
print("氏名:\(syain.simei!), 生年月日:\(syain.seinenGappi!), 入社日:\(syain.nyusyaBi!)") | |
} | |
} catch { | |
let nserror = error as NSError | |
// ここにアプリ特有のリカバリ処理を記述: | |
... | |
} | |
// If we got here, it is time to quit. | |
return .terminateNow | |
} | |
... |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
... | |
// 保存アクション: | |
@IBAction func saveAction(_ sender: AnyObject?) { | |
let busyoService = BusyoService(managedObjectContext) | |
let syainService = SyainService(managedObjectContext) | |
// -- 一旦全件削除する | |
busyoService.delete(busyoService.fetchRequest()) | |
syainService.delete(syainService.fetchRequest()) | |
// -- 2件の部署を追加する | |
let busyo1 = busyoService.create(busyoMei: "営業部") | |
let busyo2 = busyoService.create(busyoMei: "製造部") | |
// -- 3件の社員を追加する | |
let syain1 = syainService.create(simei: "吉岡三郎", | |
nyusyaBi: "2012/04/01", seinenGappi: "1976/05/22") | |
syain1.busyo = busyo1 //関係設定 : 所属 = 営業部 | |
let syain2 = syainService.create(simei: "山田花子", | |
nyusyaBi: "2014/06/22", seinenGappi: "1980/10/15") | |
syain2.busyo = busyo2 //関係設定:所属 = 製造部 | |
let syain3 = syainService.create(simei: "山田太郎", | |
nyusyaBi: "2015/04/01", seinenGappi: "1993/07/12") | |
syain3.busyo = busyo1 //関係設定 : 所属 = 営業部 | |
if !managedObjectContext.commitEditing() { | |
NSLog("\(NSStringFromClass(self.dynamicType)) 保存前の編集コミット失敗.") | |
} | |
if managedObjectContext.hasChanges { | |
do { | |
// アプリの管理オブジェクト・コンテキストに save:メッセージを送信. | |
try managedObjectContext.save() | |
} catch { | |
// エラー発生をユーザーに知らせる. | |
let nserror = error as NSError | |
NSApplication.shared().presentError(nserror) | |
} | |
} | |
// -- 氏名検索 | |
let result1 = syainService.findBySimei("山田花子") | |
printResults(title: ">氏名検索:", results: result1) | |
// -- 氏名あいまい検索 | |
let result1b = syainService.findLikeSimei("山田*") | |
printResults(title: ">氏名あいまい検索:", results: result1b) | |
// -- 生年月日検索 | |
let result2 = syainService.findBySeinenGappi("1976/05/22") | |
printResults(title: ">生年月日検索:", results: result2) | |
// -- 全件取得 | |
let result3 = syainService.findAll() | |
printResults(title: ">全件取得:", results: result3) | |
} | |
func printResults(title: String, results: [SyainMO]) { | |
print(title) | |
for syain in results { | |
print("-------------------------------") | |
print("simei: \(syain.simei!)") | |
print("seinenGappi: \(syain.seinenGappi!)") | |
print("nyusyaBi: \(syain.nyusyaBi!)") | |
print("勤続年月:\(syain.kinzokuNenGetu)") | |
} | |
} | |
... |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
import CoreData | |
/** | |
* Core Data 部署サービス. | |
*/ | |
class BusyoService { | |
// MARK: プロパティ | |
let mc: NSManagedObjectContext | |
// MARK: イニシャライザ | |
init(_ context: NSManagedObjectContext) { | |
mc = context | |
} | |
// MARK: メソッド - | |
/// 全件取得 | |
func findAll() -> [BusyoMO] { | |
let fetchReq = fetchRequest() | |
return try! mc.fetch(fetchReq) as! [BusyoMO] | |
} | |
/// 汎用クエリー検索 | |
func findByPredicate(_ pred: Predicate) -> [BusyoMO] { | |
return try! mc.fetch(fetchRequest(pred: pred)) as! [BusyoMO] | |
} | |
/// クエリーの生成 | |
func fetchRequest(pred :Predicate?=nil) -> NSFetchRequest<NSFetchRequestResult> { | |
let fetchReq: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest(entityName: "Busyo") | |
if pred != nil { | |
fetchReq.predicate = pred | |
} | |
return fetchReq | |
} | |
/// 新規作成(管理コンテキストへ追加) | |
func create(busyoMei: String) -> BusyoMO { | |
let entity = NSEntityDescription.entity(forEntityName: "Busyo", in: mc) | |
let busyo: BusyoMO = BusyoMO(entity: entity!, insertInto: mc) | |
busyo.busyoMei = busyoMei | |
return busyo | |
} | |
/// 指定部署の削除 | |
func delete(_ entity: BusyoMO) { | |
mc.delete(entity) | |
} | |
/// 条件にマッチする部署を削除 | |
func delete(_ fetchReq: NSFetchRequest<NSFetchRequestResult>) { | |
let results = try! mc.fetch(fetchReq) as! [BusyoMO] | |
for del in results { | |
delete(del) | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" standalone="no"?> | |
<!DOCTYPE database SYSTEM "file:///System/Library/DTDs/CoreData.dtd"> | |
<database> | |
<databaseInfo> | |
... | |
</databaseInfo> | |
<object type="SYAIN" id="z149"> | |
<attribute name="nyusyabi" type="string">2015/04/01</attribute> | |
<attribute name="simei" type="string">山田太郎</attribute> | |
<attribute name="seinengappi" type="string">1993/07/12</attribute> | |
<relationship name="busyo" type="0/1" destination="BUSYO" idrefs="z152"></relationship> | |
</object> | |
<object type="SYAIN" id="z150"> | |
<attribute name="nyusyabi" type="string">2012/04/01</attribute> | |
<attribute name="simei" type="string">吉岡三郎</attribute> | |
<attribute name="seinengappi" type="string">1976/05/22</attribute> | |
<relationship name="busyo" type="0/1" destination="BUSYO" idrefs="z152"></relationship> | |
</object> | |
<object type="BUSYO" id="z151"> | |
<attribute name="busyomei" type="string">製造部</attribute> | |
<relationship name="syozokusyain" type="0/0" destination="SYAIN" idrefs="z153"></relationship> | |
</object> | |
<object type="BUSYO" id="z152"> | |
<attribute name="busyomei" type="string">営業部</attribute> | |
<relationship name="syozokusyain" type="0/0" destination="SYAIN" idrefs="z149 z150"></relationship> | |
</object> | |
<object type="SYAIN" id="z153"> | |
<attribute name="nyusyabi" type="string">2014/06/22</attribute> | |
<attribute name="simei" type="string">山田花子</attribute> | |
<attribute name="seinengappi" type="string">1980/10/15</attribute> | |
<relationship name="busyo" type="0/1" destination="BUSYO" idrefs="z151"></relationship> | |
</object> | |
</database> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Cocoa | |
/** | |
* Core Data 社員サービス. | |
*/ | |
class SyainService { | |
// MARK: プロパティ | |
let mc: NSManagedObjectContext | |
// MARK: イニシャライザ | |
init(_ context: NSManagedObjectContext) { | |
mc = context | |
} | |
// MARK: メソッド - | |
/// 全件取得 | |
func findAll() -> [SyainMO] { | |
let fetchReq = fetchRequest() | |
return try! mc.fetch(fetchReq) as! [SyainMO] | |
} | |
/// 氏名検索 | |
func findBySimei(_ simei:String) -> [SyainMO] { | |
return try! mc.fetch( | |
fetchRequest(pred: Predicate(format: "simei == %@", simei))) as! [SyainMO] | |
} | |
/// 氏名あいまい検索 | |
func findLikeSimei(_ simeiLike: String) -> [SyainMO] { | |
return try! mc.fetch( | |
fetchRequest(pred: Predicate(format: "simei LIKE %@", simeiLike))) as! [SyainMO] | |
} | |
/// 生年月日検索 | |
func findBySeinenGappi(_ seinenGappi: String) -> [SyainMO] { | |
return try! mc.fetch( | |
fetchRequest(pred: Predicate(format: "seinenGappi == %@", seinenGappi))) as! [SyainMO] | |
} | |
/// 汎用クエリー検索 | |
func findByPredicate(_ pred: Predicate) -> [SyainMO] { | |
return try! mc.fetch(fetchRequest(pred: pred)) as! [SyainMO] | |
} | |
/// クエリーの生成 | |
func fetchRequest(pred :Predicate?=nil) -> NSFetchRequest<NSFetchRequestResult> { | |
let fetchReq: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest(entityName: "Syain") | |
if pred != nil { | |
fetchReq.predicate = pred | |
} | |
return fetchReq | |
} | |
/// 新規作成(管理コンテキストへ追加) | |
func create(simei: String, nyusyaBi: String, seinenGappi: String = "") -> SyainMO { | |
let entity = NSEntityDescription.entity(forEntityName: "Syain", in: mc) | |
let syain: SyainMO = SyainMO(entity: entity!, insertInto: mc) | |
syain.simei = simei | |
syain.nyusyaBi = nyusyaBi | |
syain.seinenGappi = seinenGappi | |
return syain | |
} | |
/// 更新処理 | |
// 1)条件にマッチする社員を取得して: | |
// let updSyain = findByXXX(条件) | |
// 2)データを修正: | |
// updSyain.simei = "氏名の変更" | |
// 3)データを保存: | |
// save() | |
/// 保存処理: 追加|更新 | |
func save() { | |
do { | |
try mc.save() | |
} catch let error as NSError { | |
print("保存失敗: \(error), \(error.userInfo)") | |
} | |
} | |
/// 指定社員の削除 | |
func delete(_ entity: SyainMO) { | |
mc.delete(entity) | |
} | |
/// 条件にマッチする社員を削除 | |
func delete(_ fetchReq: NSFetchRequest<NSFetchRequestResult>) { | |
let results = try! mc.fetch(fetchReq) as! [SyainMO] | |
for del in results { | |
delete(del) | |
} | |
} | |
} | |
// SyainMO 拡張 | |
extension SyainMO { | |
// 勤続年月: 計算プロパティのテスト用 | |
// 日数までは計算していない. | |
var kinzokuTuki: Int { | |
let dateFormater = DateFormatter() | |
dateFormater.dateFormat = "yyyy/MM/dd" | |
let nyusyaDate = dateFormater.date(from: self.nyusyaBi!) | |
let calendar: Calendar! = Calendar(calendarIdentifier: Calendar.Identifier.gregorian) | |
let keikaTuki = calendar.components(.month, | |
from: nyusyaDate!, to: Date(), options: []) | |
return keikaTuki.month! | |
} | |
var kinzokuNen: Int { | |
return kinzokuTuki / 12 | |
} | |
var kinzokuNenGetu: String { | |
return "\(kinzokuNen)年\(kinzokuTuki % 12)ヶ月" | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment