Updating Items

With the persistent container set up, you can now interact with Core Data. Primarily, you will do this through its viewContext. This is how you will both create new entities and save changes.

The viewContext is an instance of NSManagedObjectContext. This is the portal through which you interact with your entities. You can think of the managed object context as an intelligent scratch pad. When you ask the context to fetch some entities, the context will work with its persistent store to bring temporary copies of the entities and object graph into memory. Unless you ask the context to save its changes, the persisted data remains the same.

Inserting into the context

When an entity is created, it should be inserted into a managed object context.

Update processPhotosRequest(data:error:) to use a managed object context to insert new Photo instances.

Listing 22.4  Inserting a Photo into a context (PhotoStore.swift)

private func processPhotosRequest(data: Data?,
                                  error: Error?) -> Result<[Photo], Error> {
    guard let jsonData = data else {
        return .failure(error!)
    }

    return FlickrAPI.photos(fromJSON: jsonData)

    let context = persistentContainer.viewContext

    switch FlickrAPI.photos(fromJSON: jsonData) {
    case let .success(flickrPhotos):
        let photos = flickrPhotos.map { flickrPhoto -> Photo in
            var photo: Photo!
            context.performAndWait {
                photo = Photo(context: context)
                photo.title = flickrPhoto.title
                photo.photoID = flickrPhoto.photoID
                photo.remoteURL = flickrPhoto.remoteURL
                photo.dateTaken = flickrPhoto.dateTaken
            }
            return photo
        }
        return .success(photos)
    case let .failure(error):
        return .failure(error)
    }
}

Each NSManagedObjectContext is associated with a specific queue, and the viewContext is associated with the main queue (Core Data uses the term “queue” instead of “thread”). You have to interact with a context on the queue that it is associated with.

NSManagedObjectContext has two methods that ensure this happens: perform(_:) and performAndWait(_:). The difference between them is that perform(_:) is asynchronous and performAndWait(_:) is synchronous. Because you are returning the result of the insert operation from the photo(fromJSON:into:) method, you use the synchronous method.

You are using the map method on Array to transform one array into another array. This code:

    let numbers = [1, 2, 3]
    let doubledNumbers = numbers.map { $0 * $0 }

has the same result as this code:

    let numbers = [1, 2, 3]
    var doubledNumbers = [Int]()
    for number in numbers {
        doubledNumbers.append(number * number)
    }

Build and run the application. Although the behavior remains unchanged, the application is now backed by Core Data. In the next section, you will implement saving for both the photos and their associated image data.

Saving changes

Recall that NSManagedObject changes do not persist until you tell the context to save these changes.

Open PhotoStore.swift and update fetchInterestingPhotos(completion:) to save the changes to the context after Photo entities have been inserted into the context.

Listing 22.5  Saving photos on successful fetch (PhotoStore.swift)

func fetchInterestingPhotos(completion: @escaping (Result<[Photo], Error>) -> Void) {

    let url = FlickrAPI.interestingPhotosURL
    let request = URLRequest(url: url)
    let task = session.dataTask(with: request) {
        (data, response, error) -> Void in

        let result = self.processPhotosRequest(data: data, error: error)
        var result = self.processPhotosRequest(data: data, error: error)
        if case .success = result {
            do {
                try self.persistentContainer.viewContext.save()
            } catch {
                result = .failure(error)
            }
        }

        OperationQueue.main.addOperation {
            completion(result)
        }
    }
    task.resume()
}
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.2.15