Xcode gives error for everything I write - swift

I have been searching for a solution for two days but could not find anything on web.
I was working on a project and then instantly I was not able to declare anything new or iterate anything older that I wrote. I tried opening new project and start again but it was there again. You can see in the photo that it does need declaration for already declared variables such as cool and hype.
Now I am not able to work on any project.
import UIKit
class ViewController: UIViewController, CLLocationManagerDelegate {
var cool: Int = 2
var hype: Int = 2
hype = 2 + cool
override func viewDidLoad() {
super.viewDidLoad()
// Set up the location manager here.
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
}
// ...
}

Use of undeclared type 'CLLocationManageDelegate'
This is because you haven't imported the CoreLocation module
Add the line import CoreLocation above the import UIKit
You can't perform the assignment of hype in that scope, try moving it into viewDidLoad
You must declare a location manager variable and initialize one:
Add the line var locationManager = CLLocationManager() above your other vars.
import CoreLocation
import UIKit
class ViewController: UIViewController, CLLocationManagerDelegate {
let locationManager = CLLocationManager()
var cool: Int = 2
var hype: Int = 2
override func viewDidLoad() {
super.viewDidLoad()
hype = 2 + cool
// Set up the location manager here.
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
}
// ...
}

Actually, all your errors are totally generic, caused by syntax and other mistakes.
It should be CLLocationManager needs to be imported.
This produces errors in declaration and other places depending on it.
Variables can be declared but not manipulated outside a function on the top level of a class.
The variable locationManager has not been defined previously

Related

When/ How does swift call user created functions

Im currently learning how to code using swift. I created an app that simple displays the users location using map view.
In this code block, when does swift call the function locationManager()? I seem to have never called this function, yet it is running all the logic within it
import UIKit
import MapKit
class ViewController: UIViewController,
CLLocationManagerDelegate{
#IBOutlet weak var map: MKMapView!
#IBOutlet weak var AreaLbl: UILabel!
var locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.locationManager.requestWhenInUseAuthorization()
if CLLocationManager.locationServicesEnabled(){
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager.startUpdatingLocation()
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let locValue:CLLocationCoordinate2D = manager.location!.coordinate
print("locations = \(locValue.latitude) \(locValue.longitude)")
let userLocation = locations.last
let viewRegion = MKCoordinateRegion(center: (userLocation?.coordinate)!, latitudinalMeters: 600, longitudinalMeters: 600)
self.map.showsUserLocation = true
self.map.setRegion(viewRegion, animated: true)
}
If there are any resources you recommend for learning swift please let me know!
First, a point of order. In Swift, the name of a function includes parameters. Your function isn't named locationManager(). It's named locationManager(_:didUpdateLocations:) (One unnamed parameter and one parameter named "didUpdateLocations".)
Now to your question.
iOS and Mac OS make pretty common use of the delegate design pattern. In that pattern, one object sets itself up to be another object's "delegate". That basically means that the delegate object agrees to wait by the phone for incoming phonecalls.
When you are an object's delegate, you agree to respond to a set of messages that might be sent to you (or functions that might be called.) You "conform to a protocol" that defines the messages you need to respond to. Some of those messages might be required and some might be optional.
It's not Swift calling your function, it's the OS. Specifically the location manager.
Your viewDidLoad() function includes the line locationManager.delegate = self.
That makes you the location manager's delegate. That means that you conform to the CLLocationManagerDelegate protocol. It tells the location manager that you are ready to accept messages (function calls) from the location manager that are defined by that protocol.
When you do that, and then you tell the location manager to start updating your location with the line locationManager.startUpdatingLocation(), the location manager will start calling your locationManager(_:didUpdateLocations:) function at some future time when it detects a change to the device's location.
That is what is causing your locationManager(_:didUpdateLocations:) function to be called.

Is there any way to customize the UNnotification for local notifications in swift

I am new to Xcode and swift. I want to know that is there any way that we can customize the local notifications. If possible I also want to add a map on the notification.
Thanks in advance
You can add a target from File -> New -> Target -> Notification Content Extension
which will add an extension for your custom UI. Set the UNNotificationExtensionCategory to the string identifier.
If you want to add a map on the notification , add a Mapkit View into storyboard in the extension. I have attached the code for the map:
import UIKit
import UserNotifications
import UserNotificationsUI
import MapKit
import CoreLocation
class NotificationViewController: UIViewController, UNNotificationContentExtension{
// #IBOutlet weak var mapView: MKMapView!
#IBOutlet var label: UILabel?
fileprivate let locationManager:CLLocationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
locationManager.requestWhenInUseAuthorization()
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.distanceFilter = kCLDistanceFilterNone
locationManager.startUpdatingLocation()
// mapView.showsUserLocation = true
}
func didReceive(_ notification: UNNotification) {
//self.label?.text = notification.request.content.body
self.label?.text = "Reminder for your charging "
}
#IBAction func notibutton(_ sender: Any) {
}
}
Thanks for the help.
I tried using the notification extension identifier and called in the function in the app delegate of the main target
It worked for me also the map is displayed in the notification.

Why does locationManager popup immediately disappear when used in another class?

I am using the MapKit to use CLLocationManagerDelegate to get the user's location. If I were to request for the user's location in ViewController's viewDidLoad() function, then the popup appears, asking the user for the user's input. Note: the two properties required to ask for the location (Location When In Use, and Location Always And When In Use) is added to Info.plist
That is,
import UIKit
import MapKit
class ViewController: UIViewController, CLLocationManagerDelegate {
var locationManager: CLLocationManager?
override func viewDidLoad() {
super.viewDidLoad()
locationManager = CLLocationManager()
self.locationManager?.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager?.requestWhenInUseAuthorization()
self.locationManager?.delegate = self
self.locationManager?.startUpdatingLocation()
}
}
The code above works fine; when the program begins, it show a popup asking the user for their location.
However, If I was to create a new class MapController and put the same code inside that class, and create a new instance of MapController inside viewDidLoad(), then the popup immediately disappears when the program is run.
That is,
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let mapController = MapController(viewController: self)
mapController.initialise()
}
}
import MapKit
class MapController: NSObject, CLLocationManagerDelegate {
private let viewController: UIViewController
private var locationManager: CLLocationManager
required init(viewController: UIViewController) {
self.viewController = viewController
locationManager = CLLocationManager()
}
func initialise() {
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.requestWhenInUseAuthorization()
self.locationManager.delegate = self
self.locationManager.startUpdatingLocation()
}
}
When the code above is run, the popup asking for the user's location immediately disappears.
My question being: why does the popup stay when the locationManager code is in the viewDidLoad(), but when the code is separated into another class, and called into viewDidLoad(), it immediately disappears. Why does this happen?
How can I separate the locationManager code into another class without the popup immediately disappearing?
It's a memory management issue. In ViewController, you create a local variable named mapController in viewDidLoad. At the end of viewDidLoad, that MapController instance goes out of scope and gets deallocated.
Instead of using a local variable in viewDidLoad, create a property.
class ViewController: UIViewController {
var mapController: MapController!
override func viewDidLoad() {
super.viewDidLoad()
mapController = MapController(viewController: self)
mapController.initialise()
}
}
But this now creates a reference cycle since MapController is keeping a strong reference to the view controller.
So you also need to change the viewController property of MapController to be weak.

CLLocationManager and tvOS - RequestWhenInUseAuthorization() not prompting

I seem to be having a little trouble getting tvOS to prompt the user for location data authorization. I literally copied and pasted working code from iOS and it seems to not be prompting the user. I am using the code listed below as well as the NSLocationWhenInUseUsageDescription key with a string value. The only difference in the api that I see is on iOS it uses startupdatinglocation() and on tvOS it uses requestLocation() (similar to watchOS) I've stepped through the problem and it is infact hitting requestWhenInUseAuthorization() but simply doesn't prompt the user.
Any idea what is going on?
import UIKit
import CoreLocation
class ViewController: UIViewController {
var locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
if CLLocationManager.locationServicesEnabled(){
if CLLocationManager.authorizationStatus() == CLAuthorizationStatus.NotDetermined{
locationManager.requestWhenInUseAuthorization()
}
else if CLLocationManager.authorizationStatus() == CLAuthorizationStatus.AuthorizedWhenInUse{
locationManager.requestLocation()
}
}
}
It turns out that a CFBundleDisplayName key and $(PRODUCT_NAME)value is needed in order for the prompt to display.

Core Location in Swift

This is sample code. NSLocationAlwaysUsageDescription key in Info.plist installed. All work fine - program receives the coordinates.... displays them.....
And it continues to update them permanently! In the case of the iOS simulator - it is not critical, but in the case of a real application it is very quickly drain the battery. How to make an application launched Core Location, received location, and got shut down Core Location?
import UIKit
import CoreLocation
class ViewController: UIViewController, CLLocationManagerDelegate {
#IBOutlet var locLabel: UILabel
#IBOutlet var latLabel: UILabel
#IBOutlet var lonLabel: UILabel
var locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
#IBAction func locButton(sender: AnyObject) {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestAlwaysAuthorization()
locationManager.startUpdatingLocation()
}
func locationManager(manager:CLLocationManager, didUpdateLocations locations:AnyObject[]) {
println("locations = \(locationManager)")
var latValue = locationManager.location.coordinate.latitude
var lonValue = locationManager.location.coordinate.longitude
latLabel.text = String(latValue)
lonLabel.text = String(lonValue)
locLabel.text = "success"
}
}
If you are not much concern about high level of accuracy then you should consider startMonitoringSignificantLocationChanges instead of startUpdatingLocation. It will really make a big difference in battery draining.
This method is more appropriate for the majority of applications that just need an initial user location fix and need updates only when the user moves a significant distance. This interface delivers new events only when it detects changes to the device’s associated cell towers, resulting in less frequent updates and significantly lower power usage.
For more detail you can take a look over CLLocationManager Guide