deviceから撮影した写真(imageBuffer)がCoreDataに保存できない
- 評価
- クリップ 0
- VIEW 1,458

退会済みユーザー
前提・実現したいこと
swiftでデバイスカメラで撮影した写真をCoreDataに保存するアプリを作っています。
撮影は、NSTimerで5秒間に1回BracketedStillImageSettingsで撮影するようにしています。
が、imageBufferがCoreDataに保存できません。
該当のソースコード
// ViewController
// 撮影するコード
if let output = myImageOutput {
DispatchQueue.global().async {
let connection = output.connection(withMediaType: AVMediaTypeVideo)
let settings = [-2.0, 0.0, 2.0].map {
(bias: Float) -> AVCaptureAutoExposureBracketedStillImageSettings in AVCaptureAutoExposureBracketedStillImageSettings.autoExposureSettings(withExposureTargetBias: bias)
}
output.captureStillImageBracketAsynchronously(from: connection, withSettingsArray: settings, completionHandler: { (imageBuffer, settings, error) in
//print("imageBuffer: \(imageBuffer)")
if error == nil {
let imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(imageBuffer)!
if let image = UIImage(data: imageData) {
UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil) }
}
else {
print("error while capturing still image: \(error)")
}
})
}
}
// 毎フレームをCoreDataに保存する処理
func writeBuffer(imageBuffer: CVPixelBuffer) -> NSData {
CVPixelBufferLockBaseAddress(imageBuffer, CVPixelBufferLockFlags(rawValue: 0))
let bufferSize = CVPixelBufferGetDataSize(imageBuffer)
let width = CVPixelBufferGetWidth(imageBuffer)
let height = CVPixelBufferGetHeight(imageBuffer)
let bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer)
let baseAddress = CVPixelBufferGetBaseAddress(imageBuffer)
let colorSpace = CGColorSpaceCreateDeviceRGB()
var data: NSData = NSData(bytes: baseAddress, length: bufferSize)
CVPixelBufferUnlockBaseAddress(imageBuffer, CVPixelBufferLockFlags(rawValue: 0))
let appDelegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
let myContext: NSManagedObjectContext = appDelegate.managedObjectContext
let myEntity: NSEntityDescription! = NSEntityDescription.entity(forEntityName: "ImageData", in: myContext)
let newData = ImageData(entity: myEntity, insertInto: myContext)
newData.imageData? = data
do {
try myContext.save()
} catch {
print(error)
}
return data
}
試したこと
プロジェクト作成時にUse CoreDataにチェック入れてなかったので、新しいファイル(CoreData > DataModel)を作成し、.xcdatamodeledファイルを追加しました。
EntityはimageDataにし、TypeはBinary Dataです。
その後、Editor > Create NSManagedObject Subclassでエンティティモデルコードを生成しました。
そのあと、appDelegateに以下のコードを書き加えました
lazy var applicationDocumentsDirectory: NSURL = {
let urls = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
return urls[urls.count-1] as NSURL
}()
lazy var managedObjectModel: NSManagedObjectModel = {
// The managed object model for the application. This property is not optional. It is a fatal error for the application not to be able to find and load its model.
let modelURL = Bundle.main.url(forResource: "ImageDataBase", withExtension: "momd")!
return NSManagedObjectModel(contentsOf: modelURL)!
}()
lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = {
// Create the coordinator and store
let coordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
let url = self.applicationDocumentsDirectory.appendingPathComponent("SingleViewCoreData.sqlite")
var failureReason = "There was an error creating or loading the application's saved data."
do {
try coordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: url, options: nil)
} catch {
// Report any error we got.
var dict = [String: AnyObject]()
dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data" as AnyObject?
dict[NSLocalizedFailureReasonErrorKey] = failureReason as AnyObject?
dict[NSUnderlyingErrorKey] = error as NSError
let wrappedError = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict)
NSLog("Unresolved error \(wrappedError), \(wrappedError.userInfo)")
abort()
}
return coordinator
}()
lazy var managedObjectContext: NSManagedObjectContext = {
let coordinator = self.persistentStoreCoordinator
var managedObjectContext = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
managedObjectContext.persistentStoreCoordinator = coordinator
return managedObjectContext
}()
@available(iOS 10.0, *)
lazy var persistentContainer: NSPersistentContainer = {
let container = NSPersistentContainer(name: "coredataTest")
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
return container
}()
func saveContext () {
if #available(iOS 10.0, *) {
let context = persistentContainer.viewContext
if context.hasChanges {
do {
try context.save()
} catch {
let nserror = error as NSError
fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
}
}
} else {
if managedObjectContext.hasChanges {
do {
try managedObjectContext.save()
} catch {
let nserror = error as NSError
NSLog("Unresolved error \(nserror), \(nserror.userInfo)")
abort()
}
}
}
}
補足情報(言語/FW/ツール等のバージョンなど)
print("imageBuffer: \(imageBuffer)")とすると、imageBuffuerの中には値も入っています。
CoreDataに保存できているかどうかの確認は、Window>Devicesから実機simulator、該当アプリを選択して表示されるフォルダに特に何も追加されていないので保存できていないと判断しました。
CoreDataの使い方が間違っているのかもしれませんが、原因が何かもわかりません。
ご教授宜しくお願いします
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.09%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
質問への追記・修正、ベストアンサー選択の依頼
t_obara
2017/03/13 10:49
CoreDataの使い方が間違っているかもしれない、原因が不明であれば、それを調査するのが良いのではないでしょうか?問題が発生した場合、問題の切り分けは重要なステップです。