質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

2回答

2430閲覧

Core Dataの扱い方(コントローラにべた書きしたくない)

a_ishidaaa

総合スコア8

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2015/01/23 02:00

CoreDataを昨日学んで,sqliteへの書き込み,読み込みの仕組みは何となく理解しました。
ただ,自分の書き方として

AViewController (A)とBViewController (B)があるとして、
AとBでそれぞれあるモデルXについて書き込みたいとき

AでCoreDataをimportして

func writeData(#title:String, text:String, level:NSNumber, answer:String, id:NSNumber) { let appDel: AppDelegate = UIApplication.sharedApplication().delegate as AppDelegate let myContext: NSManagedObjectContext = appDel.managedObjectContext! let myEntity: NSEntityDescription! = NSEntityDescription.entityForName("Setsumons", inManagedObjectContext: myContext) var newData = Setsumons(entity: myEntity, insertIntoManagedObjectContext: myContext) newData.title = title newData.text = text newData.id = id newData.answer = answer newData.level = level /* Error handling */ var error: NSError? if !myContext.save(&error) { println("Could not save (error), (error?.userInfo)") } println("object saved") } func readData() { let appDel: AppDelegate = UIApplication.sharedApplication().delegate as AppDelegate let myContext: NSManagedObjectContext = appDel.managedObjectContext! let myRequest: NSFetchRequest = NSFetchRequest(entityName: "Setsumons") myRequest.returnsObjectsAsFaults = false var results: NSArray! = myContext.executeFetchRequest(myRequest, error: nil) for data in results { print("(data.title!)\n") } }

のようにべた書きする。
Bも同様にべた書きする。

とやってしまい、DRYでもないし、何より見た目が汚いし、
となってしまいます。

もう少しよい書き方はないのでしょうか。

Railsのようにやりたい・・・

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

あまりいけてないけど、基底クラスの実装ではないけど、ユーティリティクラスとしてCoreData汎用
アクセスする仕掛け。
AppDelegate が動的に作られるクラスなのでいい感じじゃない気がするけど、とりあえず、候補の1つ
としてあげときます。

CoreData に、
import Foundation
import CoreData

@objc(Bean)
class Bean: NSManagedObject {

@NSManaged var id: NSNumber @NSManaged var val: String

}
あらかじめ登録しておきます。@objc() をつけないと実行時エラーです。要注意。?本当?

CoreDataUtil.swift で保存

lang

1import Foundation 2import CoreData 3 4/** 5 * 元ネタ:http://qiita.com/watanave/items/4da9f4bc97247f780af8 6 * CoreData アクセスユーティリティ 7 */ 8class CoreDataUtil<T : NSManagedObject> { 9 10 var app:AppDelegate 11 var moc:NSManagedObjectContext 12 13 // 初期化 14 init(app:AppDelegate) { 15 self.app = app 16 self.moc = app.managedObjectContext! 17 } 18 19 // 挿入用カーソル??取得 20 func entityDescForInsert() -> T { 21 let simpleClassName = classNameForClass(T.self) 22 return NSEntityDescription.insertNewObjectForEntityForName(simpleClassName, inManagedObjectContext: moc) as T 23 24 } 25 26 // 結果取得 27 func selectAll() -> [T] { 28 let simpleClassName = classNameForClass(T.self) 29 let ed = NSEntityDescription.entityForName(simpleClassName, inManagedObjectContext: moc) 30 let fr = NSFetchRequest(entityName: simpleClassName) 31 32 var error:NSError? = nil 33 34 var arr:[T] = [T]() 35 if let results = moc.executeFetchRequest(fr, error: &error) { 36 for d in results { 37 arr.append(d as T) 38 } 39 } 40 41 return arr 42 } 43 44 // FetchRequest の結果を見る 45 func dump(data:T) { 46 47 // 元ネタ:http://safx-dev.blogspot.jp/2014/09/swift.html 48 var ref = reflect(data) 49 for var i = 0; i < ref.count; ++i { 50 let key : String = ref[i].0 51 let summary : String = ref[i].1.summary 52 let value : Any = ref[i].1.value 53 let valueType: Any.Type = ref[i].1.valueType 54 println("(key) = (value) (valueType) (summary)") 55 } 56 } 57 58 // クラスからクラスの名前を取る 59 func classNameForClass(clazz:AnyClass) -> String { 60 61 // 元ネタ:http://qiita.com/morizotter/items/9739d789d69924fd1897 62 var className = NSStringFromClass(clazz) 63 64 if let r = className.rangeOfString(".") { 65 return className.substringFromIndex(r.endIndex) 66 } else { 67 return className 68 } 69 70 } 71 72 // 挿入をコミット 73 func commit() { 74 self.app.saveContext() 75 } 76 77 78}

ViewContorlller などで

lang

1 override func viewDidLoad() { 2 super.viewDidLoad() 3 // Do any additional setup after loading the view, typically from a nib. 4 5 var cdu = CoreDataUtil<Bean>(app: UIApplication.sharedApplication().delegate as AppDelegate) 6 7 var m = cdu.entityDescForInsert() 8 m.id = 33 9 m.val = "OK" 10 cdu.commit() 11 12 var arr = cdu.selectAll() 13 for b in arr { 14 println("bean is id=(b.id) , val=(b.val)") 15 } 16 17 } 18

投稿2015/01/28 07:40

ipadcaron

総合スコア1693

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ipadcaron

2015/01/28 07:54

AppDelegate じゃなくて、UIApplicationDelegate プロトコルをとって、中身で、リフレクション使って、saveContext()呼んだり、managedObjectContext プロパティを取得したかったのですが、断念です。Objective-C を使えばできるっぽいですけど。 AppDelegte の記述が無くなれば、ライブラリで外だしにできると睨んだのですが甘い考えか、今の自分の技量では無理です;;
guest

0

ベストアンサー

雰囲気伝わりますか。ベースクラス作ってそこに型に依存しないデータread/write の仕組みを実装します。

lang

1import CoreData 2 3// NSManagedObject を基底クラスとするオブジェクトに限定する 4public class MyViewImpl<T : NSManagedObject> { 5 6 init() { 7 8 } 9 10 public func readData() -> [T] { 11 //let appDel: AppDelegate = UIApplication.sharedApplication().delegate as AppDelegate 12 //let myContext: NSManagedObjectContext = appDel.managedObjectContext! 13 //let myRequest: NSFetchRequest = NSFetchRequest(entityName: "Setsumons") 14 //myRequest.returnsObjectsAsFaults = false 15 //var results: NSArray! = myContext.executeFetchRequest(myRequest, error: nil) 16 17 /** 18 * 19 * NSFetchRequest(entityName: "Setsumons") 20 * "" のところを、write 同様にする 21 */ 22 23 24 var arr:Array<T> = [] 25 26 var str = NSStringFromClass(T) 27 28 29 return arr 30 } 31 32 // オーバーロード、可変引数。並べたアイテムを登録する 33 public func writeData(datas:T...) { 34 //let appDel = UIApplication.sharedApplication().delegate as AppDelegate 35 //let myContext: NSManagedObjectContext = appDel.managedObjectContext! 36 //let myEntity: NSEntityDescription! = NSEntityDescription.entityForName("Setsumons", inManagedObjectContext: myContext) 37 //var newData = Setsumons(entity: myEntity, insertIntoManagedObjectContext: myContext) 38 39 /** 40 * 41 * entityForName の第一引数に渡す String 文字列は、Tのインスタンスから、NSStringFromClass() で取得すればOK 42 */ 43 } 44 45 // オーバーロード、配列を引数に取る。配列要素のアイテムを登録する 46 public func writeData(datas:[T]) { 47 48 } 49 50 // <T> のクラス名=CoreData に登録したテーブル名を返す。 51 func simpleClassName() -> String { 52 var className = NSStringFromClass(T) 53 var range = className.rangeOfString(".") 54 return className.substringFromIndex(range!.endIndex) 55 } 56} 57 58// CoreData にアクセスするエンティティ、Sumons テーブルをあらかじめ定義しておく 59public class Sumons : NSManagedObject { 60 // Primary key 61 @NSManaged var id:NSInteger 62 63 // member 64 @NSManaged var text:String 65 // とりあえず2つだけ定義 66}

投稿2015/01/23 17:01

ipadcaron

総合スコア1693

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

a_ishidaaa

2015/01/26 14:43

ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問