I'm working on a group project application in Swift for iOS that allows users to save Location(s) as part of a Tour using Firebase. Our User object is a custom class that we hope to conform to Codable for use with the CodableFirebase CocoaPod. However, the issue arises when trying to conform the Location object to Codable because it also has to conform to MKAnnotation... and we are all fairly new to this. It's possible that some solutions have gone over my head... entirely possible.
This is our Location object:
import Foundation
import MapKit
import CoreLocation
import CodableFirebase
class Location: NSObject, MKAnnotation {
var coordinate: CLLocationCoordinate2D
var locationName: String?
var locationDescription: String?
var locationImage: UIImage?
init(coordinate: CLLocationCoordinate2D, locationName: String, locationDescription: String, locationImage: UIImage) {
self.coordinate = coordinate
self.locationName = locationName
self.locationDescription = locationDescription
self.locationImage = locationImage
}
}
And this is our User model object:
import UIKit
import CloudKit
class User {
//MARK: - Editable Public Profile Info
var firstName: String
var lastName: String
var userStateOfOrigin: States
var userImage: UIImage?
var aboutMe: String
var languages: [Language]
//MARK: - Editable Personal Info (Includes all Public Profile info)
var email: String?
var phoneNumber: String?
//MARK: - Hidden Variables
var userId: String
var userCreatedTours: [Tour]
var savedLocations: [Location]
var savedTours: [Tour]
var bookedTours: [Tour]
var previouslyExperiencedTours: [Tour]
var userRating: [Rating]
init(firstName: String, lastName: String, userStateOfOrigin: States, userImage: UIImage? = nil, aboutMe: String, languages: [Language] = [], email: String?, phoneNumber: String? = "", userId: String, userCreatedTours: [Tour] = [], savedLocations: [Location] = [], savedTours: [Tour] = [], bookedTours: [Tour] = [], previouslyExperiencedTours: [Tour] = [], userRating: [Rating] = []) {
// editable Public info
self.firstName = firstName
self.lastName = lastName
self.userStateOfOrigin = userStateOfOrigin
self.userImage = userImage
self.aboutMe = aboutMe
self.languages = languages
// editable personal info
self.email = email
self.phoneNumber = phoneNumber
// Hidden Variables
self.userId = userId
self.userCreatedTours = userCreatedTours
self.savedLocations = savedLocations
self.savedTours = savedTours
self.bookedTours = bookedTours
self.previouslyExperiencedTours = previouslyExperiencedTours
self.userRating = userRating
}
}
We do have a few other custom objects, but I think once this issue is solved, we should be able to easily conform those to Codable. Ultimately, it would be great to be able to make these both conform to Codable for easy use with Firebase. However, if that's not possible, or the most prudent route, I'm very open to suggestions. I really appreciate it.
A couple of observations:
MKAnnotationprotocol hastitleandsubtitleproperties (that many annotation views use). I might suggest renaminglocationNameandlocationDescription, respectively.I’d suggest making these properties
dynamic, that way if you ever update them, the changes will be updated on their respective annotation views.For example, the documentation for
coordinatesays:The easy way to do this in Swift is with the
dynamickeyword.To make this
Codable, either:the properties must be
Codable, too; oryou will need to manually implement
init(from:)andencode(to:)to do the decoding and encoding, respectively. See Encoding and Decoding Custom Types for examples.Given that neither
CLLocationCoordinate2DnorUIImageconform toCodable, I’d lean towards this second option.A very minor point, but I might not use a type name of
Location, but rather using something withAnnotationin the name, to make it clear what the object is. It also helps avoid confusion with location objects, e.g.CLLocation. I usedCustomAnnotationbelow, which isn’t a great name, but hopefully you can come up with a name that makes more sense within your app, but also hasAnnotationwithin the name.Thus, pulling this all together you might do something like: