I am a “newbie” to Coding and Swift. To better understand the Code I have started breaking it up into chunks and formatting as per my example below. My questions are 1) is “Is this bad practice”? 2) “Is it likely to lead to problems later on”?
let location = LocationHelper.currentLocation
class LocationHelper: NSObject, ObservableObject {
static let shared = LocationHelper()
static let DefaultLocation = CLLocationCoordinate2D(
latitude: (
thisCardPositionLatidude),
longitude: (
thisCardPositionLongitude))
static var currentLocation: CLLocationCoordinate2D {
guard let location = shared.locationManager.location else {
return DefaultLocation
}
return location.coordinate
}
private let locationManager = CLLocationManager()
private override init() {
super.init()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
}
}
extension LocationHelper: CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager,
didUpdateLocations locations: [CLLocation]) { }
public func locationManager(_ manager: CLLocationManager,
didFailWithError error: Error) {
print("Location manager failed with error: \(error.localizedDescription)")
}
public func locationManager(_ manager: CLLocationManager,
didChangeAuthorization status: CLAuthorizationStatus) {
print("Location manager changed the status: \(status)")
}
}
A good practice is to use code formatter to get proper identation…😉
let location = LocationHelper.currentLocation
class LocationHelper: NSObject, ObservableObject {
static let shared = LocationHelper()
static let DefaultLocation = CLLocationCoordinate2D(
latitude: thisCardPositionLatidude,
longitude: thisCardPositionLongitude)
static var currentLocation: CLLocationCoordinate2D {
guard let location = shared.locationManager.location else { return DefaultLocation }
return location.coordinate
}
private let locationManager = CLLocationManager()
private override init() {
super.init()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
}
}
extension LocationHelper: CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager,
didUpdateLocations locations: [CLLocation]) { }
public func locationManager(_ manager: CLLocationManager,
didFailWithError error: Error) {
print("Location manager failed with error: \(error.localizedDescription)")
}
public func locationManager(_ manager: CLLocationManager,
didChangeAuthorization status: CLAuthorizationStatus) {
print("Location manager changed the status: \(status)")
}
}
I suppose your question is about extension ?
- it is not a bad practice, on the contrary this is a very common practice
- I personally usually have the func directly in the class, but that's a personal choice.
There are differences however,
- for subclassing: https://stackoverflow.com/questions/46121653/difference-between-adopting-protocolextension-vs-using-instance-of-a-class
- to create custom initialisers. See interesting explanation by ekimo here: https://developer.apple.com/forums/thread/112217
Consider this example:
struct WithoutExtension {
var x : Int = 10
init(value: Int) {
self.x = value
}
}
struct WithExtension {
var x : Int = 10
}
extension WithExtension {
init(value: Int) {
self.x = value
}
}
let with = WithExtension()
let with2 = WithExtension(value: 20)
let without = WithoutExtension() // Error: Missing argument for parameter 'value' in call
let without2 = WithoutExtension(value: 20)
Or convenience init for classes
class WithoutExtension {
var x : Int = 10
init(value: Int) {
self.x = value
}
}
class WithExtension {
var x : Int = 10
}
extension WithExtension {
convenience init(value: Int) {
self.x = value
}
}
let with = WithExtension()
let with2 = WithExtension(value: 20)
let without = WithoutExtension() // Error: Missing argument for parameter 'value' in call
let without2 = WithoutExtension(value: 20)
In both cases:
let without = WithoutExtension()
will not compile, with error: Error: Missing argument for parameter 'value' in call But
let with = WithExtension()
will compile. Note: you don't need parenthesis round latitude or longitude parameters.