First, we will start with saving reviews into Core Data. Open up ReviewFormViewController.swift and above the @IBOutlets add the following variable:
var selectedRestaurantID:Int?
Next, delete everything inside your onSavedTapped(:) method and then add the following:
@IBAction func onSaveTapped(_ sender: Any) {
var item = ReviewItem()
item.name = tfName.text
item.customerReview = tvReview.text
item.restaurantID = selectedRestaurantID
item.rating = Float(ratingView.rating)
let manager = CoreDataManager()
manager.addReview(item)
dismiss(animated: true, completion: nil)
}
This code is all we need to do to save an item into Core Data using our CoreDataManager. To display reviews for a particular restaurant, we need to save all reviews with a restaurant identifier. Then, when we go to a certain restaurant, we will use the restaurant identifier to search Core Data to see if there are any saved reviews. We pass this identifier using a segue.
- Open RestaurantDetail.storyboard and select the segue we are using to go to the ReviewForm.
- In the Attributes inspector of the Utilities panel, update Identifier under Storyboard Segue to say showReview. Then, hit Enter.
- Next, we need to make sure that, when a user creates a review, we pass restaurantID to the Review Form View Controller. We need to update our RestaurantItem so it has an ID. Open RestaurantItem after var imageURL:String? and add the following:
var restaurantID:String?
- Next, inside the enum CodingKeys:String add the new case:
case restaurantID = "id"
- Open RestaurantDetailViewController.swift and add this method after the viewDidLoad() method (ignore the errors for now):
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let identifier = segue.identifier {
switch identifier {
case Segue.showReview.rawValue:
showReview(segue: segue)
default:
print("Segue not added")
}
}
}
The prepare() method inside the RestaurantDetailViewController will check for the showReview segue identifier. If successful, it will call the showReview() method, which will take you to the Reviews list.
- Next, add the following method above the createRating() method inside the private extension:
func showReview(segue:UIStoryboardSegue) {
guard let navController = segue.destination as? UINavigationController,
let viewController = navController.topViewController as? ReviewFormViewController else {
return
}
viewController.selectedRestaurantID = selectedRestaurant?.restaurantID
}
- While we are cleaning up, move the initialize() method into the private extension.
- Next, open ReviewFormViewController; let's create a private extension and moveonSaveTapped(_:) into it. Then, delete everything inside the method and update the method with the following:
private extension ReviewFormViewController {
@IBAction func onSaveTapped(_ sender: Any) {
var item = ReviewItem()
item.name = tfName.text
item.customerReview = tvReview.text
item.restaurantID = selectedRestaurantID
item.rating = Float(ratingView.rating)
let manager = CoreDataManager()
manager.addReview(item)
dismiss(animated: true, completion: nil)
}
}
Let's make sure we are passing the restaurantID by adding a print statement inside ReviewFormViewController.
- Inside the -viewDidLoad() method, add the following print statement:
print(selectedRestaurantID as Any)
Let's build and run the project by hitting the Play button (or use ⌘ + R). You should now be able to see restaurantID in the console. You can create a review and, after you save the review, you are brought back to the restaurant detail view, but we are still missing displaying our reviews in restaurant details. We will work on this later in this chapter. Before we do that, let's look at how we can save photos into Core Data.