Core Dataの扱い方(コントローラにべた書きしたくない)
解決済
回答 2
投稿
- 評価
- クリップ 0
- VIEW 1,753
ただ,自分の書き方として
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のようにやりたい・・・
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
checkベストアンサー
0
import CoreData
// NSManagedObject を基底クラスとするオブジェクトに限定する
public class MyViewImpl<T : NSManagedObject> {
init() {
}
public func readData() -> [T] {
//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)
/**
*
* NSFetchRequest(entityName: "Setsumons")
* "" のところを、write 同様にする
*/
var arr:Array<T> = []
var str = NSStringFromClass(T)
return arr
}
// オーバーロード、可変引数。並べたアイテムを登録する
public func writeData(datas:T...) {
//let appDel = 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)
/**
*
* entityForName の第一引数に渡す String 文字列は、Tのインスタンスから、NSStringFromClass() で取得すればOK
*/
}
// オーバーロード、配列を引数に取る。配列要素のアイテムを登録する
public func writeData(datas:[T]) {
}
// <T> のクラス名=CoreData に登録したテーブル名を返す。
func simpleClassName() -> String {
var className = NSStringFromClass(T)
var range = className.rangeOfString(".")
return className.substringFromIndex(range!.endIndex)
}
}
// CoreData にアクセスするエンティティ、Sumons テーブルをあらかじめ定義しておく
public class Sumons : NSManagedObject {
// Primary key
@NSManaged var id:NSInteger
// member
@NSManaged var text:String
// とりあえず2つだけ定義
}
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
0
アクセスする仕掛け。
AppDelegate が動的に作られるクラスなのでいい感じじゃない気がするけど、とりあえず、候補の1つ
としてあげときます。
CoreData に、
import Foundation
import CoreData
@objc(Bean)
class Bean: NSManagedObject {
@NSManaged var id: NSNumber
@NSManaged var val: String
}
あらかじめ登録しておきます。@objc() をつけないと実行時エラーです。要注意。?本当?
CoreDataUtil.swift で保存
import Foundation
import CoreData
/**
* 元ネタ:http://qiita.com/watanave/items/4da9f4bc97247f780af8
* CoreData アクセスユーティリティ
*/
class CoreDataUtil<T : NSManagedObject> {
var app:AppDelegate
var moc:NSManagedObjectContext
// 初期化
init(app:AppDelegate) {
self.app = app
self.moc = app.managedObjectContext!
}
// 挿入用カーソル??取得
func entityDescForInsert() -> T {
let simpleClassName = classNameForClass(T.self)
return NSEntityDescription.insertNewObjectForEntityForName(simpleClassName, inManagedObjectContext: moc) as T
}
// 結果取得
func selectAll() -> [T] {
let simpleClassName = classNameForClass(T.self)
let ed = NSEntityDescription.entityForName(simpleClassName, inManagedObjectContext: moc)
let fr = NSFetchRequest(entityName: simpleClassName)
var error:NSError? = nil
var arr:[T] = [T]()
if let results = moc.executeFetchRequest(fr, error: &error) {
for d in results {
arr.append(d as T)
}
}
return arr
}
// FetchRequest の結果を見る
func dump(data:T) {
// 元ネタ:http://safx-dev.blogspot.jp/2014/09/swift.html
var ref = reflect(data)
for var i = 0; i < ref.count; ++i {
let key : String = ref[i].0
let summary : String = ref[i].1.summary
let value : Any = ref[i].1.value
let valueType: Any.Type = ref[i].1.valueType
println("\(key) = \(value) \(valueType) \(summary)")
}
}
// クラスからクラスの名前を取る
func classNameForClass(clazz:AnyClass) -> String {
// 元ネタ:http://qiita.com/morizotter/items/9739d789d69924fd1897
var className = NSStringFromClass(clazz)
if let r = className.rangeOfString(".") {
return className.substringFromIndex(r.endIndex)
} else {
return className
}
}
// 挿入をコミット
func commit() {
self.app.saveContext()
}
}
ViewContorlller などで
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
var cdu = CoreDataUtil<Bean>(app: UIApplication.sharedApplication().delegate as AppDelegate)
var m = cdu.entityDescForInsert()
m.id = 33
m.val = "OK"
cdu.commit()
var arr = cdu.selectAll()
for b in arr {
println("bean is id=\(b.id) , val=\(b.val)")
}
}
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.22%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
2015/01/26 23:43