照片识别应用程序的核心数据实现

时间:2018-10-09 12:47:14

标签: swift core-data

我正在创建照片识别应用程序,该应用程序使用核心数据来持久保存从照片库或相机加载到应用程序中的用户图像。我一直在遵循一个发现here的指南,该指南使用核心数据保存和加载图像,但是在视图控制器中显示它们时遇到了麻烦:

将图像加载到CameraViewController中的应用程序中,并在ImpagePickerController函数上调用PrepareImageforSaving方法:

class CameraViewController: SharedImagePickerController {

let session = URLSession.shared

var landmark: Landmark!

var dataController: DataController!


/// The Core Data managed context
var managedContext : NSManagedObjectContext?


@IBOutlet weak var activityIndicator: UIActivityIndicatorView!
@IBOutlet weak var landmarkResults: UITextView!
@IBOutlet weak var CameraPhoto: UIImageView!


@IBAction func chooseImage(_ sender: Any) {

    let sharedImagePickerController = UIImagePickerController()
    sharedImagePickerController.delegate = self

    let actionSheet = UIAlertController(title: "Photo  Source", message: "Choose a source", preferredStyle: .actionSheet)

    actionSheet.addAction(UIAlertAction(title: "Camera", style: .default, handler: {(action:UIAlertAction) in
        sharedImagePickerController.sourceType = .camera
        self.present(sharedImagePickerController, animated: true, completion: nil)
    }))

    actionSheet.addAction(UIAlertAction(title: "Photo Library", style: .default, handler: {(action:UIAlertAction) in
        sharedImagePickerController.sourceType = .photoLibrary
        self.present(sharedImagePickerController, animated: true, completion: nil)
    }))

    actionSheet.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))

    self.present(actionSheet, animated: true, completion: nil )
}

    override func viewDidLoad() {
    super.viewDidLoad()
    let tapGesture = UITapGestureRecognizer(target: self, action: Selector(("imageTapped:")))
    CameraPhoto.addGestureRecognizer(tapGesture)
    CameraPhoto.isUserInteractionEnabled = true
    activityIndicator.hidesWhenStopped = true
    coreDataSetup()

}


func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
    if let pickedImage = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
        CameraPhoto.contentMode = .scaleAspectFit
        CameraPhoto.image = pickedImage
        activityIndicator.startAnimating()
        let binaryImageData = base64EncodeImage(pickedImage)
        createRequest(with: binaryImageData)



    dismiss(animated: true, completion: nil)
    prepareImageForSaving(pickedImage)

    }
}

func saveLandmark(givenName: String) {
    let entity = NSEntityDescription.entity(forEntityName: "Landmark", in: dataController.viewContext)
    let item = NSManagedObject(entity: entity!, insertInto: dataController.backgroundContext!)
    item.setValue(givenName, forKey: "name")
    do {
        try dataController.backgroundContext!.save()
    } catch {
        print("Something went wrong")
    }
}

然后在LandmarkListViewController中,在ViewDidLoad上调用loadImages函数:

class LandmarkListViewController: UIViewController, UITableViewDelegate {


@IBOutlet var tableView: UITableView!

var dataController: DataController!

var tableViewDataSource = TableViewDataSource()


override func viewDidLoad() {
    super.viewDidLoad()
    loadImages { (landmarks) -> Void in

        var newLandmarks : [Landmark] = []

        for landmark in landmarks {

            // filter out duplicates
            let isDuplicate = self.tableViewDataSource.data.contains {
                return $0.id == landmark.id
            }

            if !isDuplicate {
                newLandmarks.append(landmark)
            }
        }

        var paths : [IndexPath] = []
        let start = self.tableViewDataSource.data.count
        self.tableViewDataSource.data += newLandmarks.map { return (image:$0.image ?? UIImage(),id:$0.id ?? 0.0) }
        let end = self.tableViewDataSource.data.count

        for i in start..<end {
            paths.append(IndexPath(row: i, section: 0))
        }

        // make sure it updates happen on the main thread
        Run.main {
            self.tableView.beginUpdates()
            self.tableView.insertRows(at: paths, with: UITableView.RowAnimation.fade)
            self.tableView.endUpdates()
        }
    }
}


override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    if let indexPath = tableView.indexPathForSelectedRow {
    tableView.deselectRow(at: indexPath, animated: false)
    tableView.reloadRows(at: [indexPath], with: .fade)
    }
}

override func viewDidDisappear(_ animated: Bool) {
    super.viewDidDisappear(animated)
}

// Actions

@IBAction func closeButtonPressed(_ sender: Any) {
    navigationController?.dismiss(animated: true, completion: nil)
}

}


 extension LandmarkListViewController:NSFetchedResultsControllerDelegate {

func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
    switch type {
    case .insert:
        tableView.insertRows(at: [newIndexPath!], with: .fade)
        break
    case .delete:
        tableView.deleteRows(at: [indexPath!], with: .fade)
        break
    case .update:
        tableView.reloadRows(at: [indexPath!], with: .fade)
    case .move:
        tableView.moveRow(at: indexPath!, to: newIndexPath!)
    }
}

func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange sectionInfo: NSFetchedResultsSectionInfo, atSectionIndex sectionIndex: Int, for type: NSFetchedResultsChangeType) {
    let indexSet = IndexSet(integer: sectionIndex)
    switch type {
    case .insert: tableView.insertSections(indexSet, with: .fade)
    case .delete: tableView.deleteSections(indexSet, with: .fade)
    case .update, .move:
        fatalError("Invalid change type in controller(_:didChange:atSectionIndex:for:). Only .insert or .delete should be possible.")
    }
}


func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
    tableView.beginUpdates()
}

func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
    tableView.endUpdates()
}

}   

我很想念我为什么失踪。我是Core Data和程序设计的新手,所以如果我错过了明显的事情,请不要提出任何建议。感谢您的反馈。

完整代码在这里:https://github.com/PeteChambers/WhatLandmark-

0 个答案:

没有答案