Thank you for your reply!
I did not add too many files until I got some feedback.
I guess that you would like to see RestaurantItem.swift & MapDataManager.swift:
l//
// RestaurantItem.swift
// EatOut
//
// Created by Tony Hudson on 12/07/2021.
//
import UIKit
import MapKit
class RestaurantItem: NSObject, MKAnnotation {
var name: String?
var cuisines: [String] = []
var lat: Double?
var long: Double?
var address: String?
var postalCode: String?
var state: String?
var imageURL: String?
var restaurantID: Int?
init (dict: [String: AnyObject]) {
if let lat = dict["lat"] as? Double { self.lat = lat}
if let long = dict["long"] as? Double { self.long = long}
if let name = dict["name"] as? String { self.name = name}
if let cuisines = dict["cuisines"] as? [String] { self.cuisines = cuisines}
if let address = dict["address"] as? String { self.address = address}
if let postalCode = dict["postalCode"] as? String { self.postalCode = postalCode}
if let state = dict["state"] as? String { self.state = state}
if let image = dict["imageURL"] as? String { self.imageURL = image}
if let id = dict["id"] as? Int { self.restaurantID = id}
}
var coordinate: CLLocationCoordinate2D {
guard let lat = lat, let long = long else {
return CLLocationCoordinate2D()
}
return CLLocationCoordinate2D(latitude: lat, longitude: long)
}
var title: String? {
return name
}
var subtitle: String? {
if cuisines.isEmpty { return ""}
else if cuisines.count == 1 { return cuisines.first}
else { return cuisines.joined(separator: ", ")
}
}
}
// MapDataManager.swift
// EatOut
//
// Created by Tony Hudson on 12/07/2021.
//
import Foundation
import MapKit
class MapDataManager: DataManager {
fileprivate var items: [RestaurantItem] = []
var annotations: [RestaurantItem] {
return items
}
func fetch(completion: (_ annotations: [RestaurantItem]) -> ()){
if items.count > 0 { items.removeAll() }
for data in load(file: "MapLocations") {
items.append(RestaurantItem(dict: data))
}
completion(items)
}
func currentRegion(latDelta: CLLocationDegrees, longDelta: CLLocationDegrees) -> MKCoordinateRegion {
guard let item = items.first else {
return MKCoordinateRegion()
}
let span = MKCoordinateSpan(latitudeDelta: latDelta, longitudeDelta: longDelta)
return MKCoordinateRegion(center: item.coordinate, span: span)
}
}
Could you explain what you said that annotations was not used?
Post
Replies
Boosts
Views
Activity
Have working back through the code steps and found that I had missed several lines of code, so is now working!
Thanks!
Right! The Playground code now works and in the ExploreDataManager.swift with the print(data) statement it prints the data in the debug area.
On checking my code with the code I downloaded I found that the instructions were ambigious and I had put a statement in the wrong place in the ExploreViewController.swift file. Viz. let Manager = ExploreDataManager() should have been after The first @IBOutlet statement.
But alas I still get the explore screen without the image and title when I run the app.
I don't know if this is relevant, when the app is run I get a warning
Here is the screen shot:
Could this be the reason that the images and text are not being loaded?
As a check I have tried to simulate the error in Playground.
This was also suggested in the book. Swear that when I first tried it some time ago it worked!
The Playground produces the table in LiveView but is empty.
Here is the code:
import UIKit
import PlaygroundSupport
class TableViewExampleController: UIViewController, UITableViewDataSource {
var tableView: UITableView?
var names: [String] = ["Jane", "Akhil", "Divij"]
override func viewDidLoad() {
super.viewDidLoad()
self.view.bounds = CGRect(x: 0, y: 0, width: 375, height: 667)
createTableView()
}
func createTableView() {
self.tableView = UITableView(frame: CGRect(x: 0, y: 0, width:
self.view.frame.width, height: self.view.frame.height))
self.tableView?.dataSource = self
self.tableView?.backgroundColor = .white
self.tableView?.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
self.view.addSubview(self.tableView!)
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
names.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
let name = names[indexPath.row]
cell.textLabel?.text? = name
return cell
}
}
PlaygroundPage.current.liveView = TableViewExampleController()
It seems strange that both the main project and Playground suffer from the same problem?
Is there anything in the setup or preferences that would cause this?
I don't want to reinstall Xcode as it would mean I would have to start from the beginning again.
Can anyone suggest why this behaviour is occurring?
As part of the instructions in the book, in the ExploreDataManager.swift i test that the data works by changing the line:
items.append(ExploreItem(dict: data))
With:
print(data)
It should print the data in the debug area, but it does not?
What could cause this to happen?
Is this what meant when you said have I checked loadData()?
Hi OOPer
The plist file is definitely added to the project, as I had to Create a new group called Model and then a new file which was the ExploreDat.plist.
It is definitely in the Project Navigator.
I tried to add a file using the paperclip icon below but when I go the the folder where it is stored, it is gray'd out. That would not prove much as it is a collection of 31 items with 2 fields (name & Image).
I believe this is the code that you said I didn't show?
ExploreView Controller:
// ExploreViewController.swift
// EatOut
//
// Created by Tony Hudson on 16/05/2021.
//
import UIKit
class ExploreViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "header", for: indexPath)
return headerView
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return manager.numberOfItems()
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "exploreCell", for: indexPath) as! ExploreCell
let item = manager.explore(at: indexPath)
cell.lblName.text = item.name
cell.imgExplore.image = UIImage(named: item.image)
return cell
}
@IBOutlet weak var collectionView: UICollectionView!
let manager = ExploreDataManager()
override func viewDidLoad() {
super.viewDidLoad()
let manager = ExploreDataManager()
manager.fetch()
// Do any additional setup after loading the view.
}
@IBAction func unwindLocationCancel(segue: UIStoryboardSegue) {
}
}
```
One observation: the last IBAction, doesn't appear to be connected (no dot in the circle).
As far as I know the cell is defined in the ExploreCell.swift shown in. first post.
The author is trying to teach the readers MVC so the model files are:
ExploreItem.swift
ExploreDataManager.swift
The View item is ExploreCell.swift
Unfortunately, as far as I can see the code is correct against the author version I downloaded from the book.
If its not a typo the only other thing is that I have missed one of the steps.
If you can help I would be grateful!
Thank you that worked!
I have noticed that the segue icon is incorrect as I added a new View Controller and linked as I explained in the first post. I used Show but it should be an icon with a diagonal line with 2 dots at each end. Not sure what that is, but guess its the icon for a Tab Bar branch.
I find that the book does not explain the methods very well. The book said 'Click on Main.storyboard and click on View Controller icon of the newly added View Controller Scene in the document outline'. It did not say anything about clicking on the new scene tab bar as you described. this is not the first instruction that the author has described ambiguously,
Thank you for your help!
I'm an *****! I saw the segue when I linked to the exit icon but did not click on it, as I thought that as there was only one item it was automatically choosen!
I have abandoned this version of the project as an error occurred saying it could not connect to my profile as it was missing, so I uninstalled Xcode and reinstalled.
Still can't solve this error!
As far as I can see there are no constraint errors, as there is not a warning triangle showing on the scene.
Here is more detail of the error:
libsystem_kernel.dylib`__pthread_kill:
0x1bd7c3e38 +0: mov x16, #0x148
0x1bd7c3e3c +4: svc #0x80 0x1bd7c3e40 +8: b.lo 0x1bd7c3e5c ; +36
0x1bd7c3e44 +12: stp x29, x30, [sp, #-0x10]!
0x1bd7c3e48 +16: mov x29, sp
0x1bd7c3e4c +20: bl 0x1bd7bce10 ; cerror_nocancel
0x1bd7c3e50 +24: mov sp, x29
0x1bd7c3e54 +28: ldp x29, x30, [sp], #0x10
0x1bd7c3e58 +32: ret
0x1bd7c3e5c +36: ret
What does the +36 mean, which is on the line with the error?
I believe that the error started when the class was first formed. The class 'LocationViewController' was created in the Location folder by creating a new Cocoa Touch file in the Location folder, then Ctrl + dragging from the table view in the scene. this produced an outlet which was named 'tableView'. Then the 'Datasource & Delegate' outlets were formed by dragging from the connection view 'Datasource & Delegate' to the LocationViewController. after a bit of coding, the following code is tested:
//
// LocationViewController.swift
// LetsEat3
//
// Created by Tony Hudson on 27/04/2021.
//
import UIKit
class LocationViewController: UIViewController, UITableViewDataSource {
@IBOutlet weak var tableView: UITableView!
let manager = LocationDataManager()
override func viewDidLoad() {
super.viewDidLoad()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) - Int {
10
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) - UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "locationCell", for: indexPath)
cell.textLabel?.text = "A Cell"
return cell
}
The code builds OK, but fails when I click on the Location button.
It seems to suggest that there is a layout error, but I have checked for in consistencies but there are none.
Does this make the solving of this problem any easier?
}
For the record I have sorted this out!
All you need to do is goto File menu/New/Editor.
I think everybody above was trying to make the problem too complicated, whereas the solution was so simple if you are an expert you do not think of the simplest solution, but overkill the question when it is staring you in the face.