This is my button click code
#IBAction func loc_btn_actn(_ sender: Any) {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
shyMap.showsUserLocation = true
}
this is my locationManager function
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let userLocation:CLLocation = locations[0] as CLLocation
manager.stopUpdatingLocation()
let coordinations = CLLocationCoordinate2D(latitude: userLocation.coordinate.latitude,longitude: userLocation.coordinate.longitude)
let span = MKCoordinateSpanMake(0.2,0.2)
let region = MKCoordinateRegion(center: coordinations, span: span)
shyMap.setRegion(region, animated: true)
}
when i am clicking button i am getting app delegate error cant able to track location
Related
I am trying to make a small iPad application which features an 'About' page. I have run into an issue when I try to change the class of the about page scene which is displayed modally, as the application crashes when the user tries to access this page. I wish to change its class to "ViewController", which is the same class as my main window (map view), to create actions from buttons on the 'About' page.
Currently I am unable to ctrl+drag to the .Swift file from the About page unless I change its class. Not sure why this is happening :(
The error printed to the console is as follows:
fatal error: unexpectedly found nil while unwrapping an Optional value
0 specialised_fatalErrorMessage(StaticString, StaticString, StaticString, Uint) -> () –
Here is my storyboard with scenes:
Here is the full ViewController.Swift code:
import UIKit
import MapKit
import CoreLocation
class ViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate, UISearchBarDelegate, UIPopoverPresentationControllerDelegate {
var location: CLLocation!
let locationManager = CLLocationManager()
// Map variables
var searchController:UISearchController!
var annotation:MKAnnotation!
var localSearchRequest:MKLocalSearchRequest!
var localSearch:MKLocalSearch!
var localSearchResponse:MKLocalSearchResponse!
var error:NSError!
var pointAnnotation:MKPointAnnotation!
var pinAnnotationView:MKPinAnnotationView!
#IBOutlet weak var mapView: MKMapView!
#IBOutlet weak var segmentedControl: UISegmentedControl!
#IBOutlet weak var showSearchBar: UIBarButtonItem!
#IBOutlet weak var addButton: UIBarButtonItem!
#IBOutlet weak var moreStuff: UIBarButtonItem!
#IBAction func addButton(sender: AnyObject) {
let annotation = MKPointAnnotation()
annotation.coordinate = CLLocationCoordinate2D(latitude: self.mapView.userLocation.coordinate.latitude, longitude: self.mapView.userLocation.coordinate.longitude)
self.mapView.addAnnotation(annotation)
self.locationManager.startUpdatingLocation()
}
#IBAction func showSearchBar(sender: UIBarButtonItem!) {
searchController = UISearchController(searchResultsController: nil)
searchController.hidesNavigationBarDuringPresentation = false
self.searchController.searchBar.delegate = self
presentViewController(searchController, animated: true, completion: nil)
}
#IBAction func moreStuff(sender: AnyObject) {
self.performSegueWithIdentifier("showMoreStuff", sender:self)
}
#IBAction func refresh(sender: AnyObject) {
self.locationManager.startUpdatingLocation()
}
#IBAction func segmentedControl(sender: UISegmentedControl!) {
if sender.selectedSegmentIndex == 0{
mapView.mapType = MKMapType.Standard
}
else if sender.selectedSegmentIndex == 1{
mapView.mapType = MKMapType.Satellite
}
else if sender.selectedSegmentIndex == 2{
mapView.mapType = MKMapType.Hybrid
}
}
override func viewDidLoad() {
super.viewDidLoad()
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.requestWhenInUseAuthorization()
self.locationManager.startUpdatingLocation()
self.mapView.showsUserLocation = true
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// location delegate methods
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location = locations.last
let center = CLLocationCoordinate2D(latitude: location!.coordinate.latitude, longitude: location!.coordinate.longitude)
let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01))
self.mapView.setRegion(region, animated: true)
self.locationManager.stopUpdatingLocation()
}
func locationManager(manager: CLLocationManager, didFailWithError error: NSError)
{
print("Error code: " + error.localizedDescription)
}
func searchBarSearchButtonClicked(searchBar: UISearchBar){
searchBar.resignFirstResponder()
dismissViewControllerAnimated(true, completion: nil)
if self.mapView.annotations.count != 0{
annotation = self.mapView.annotations[0]
self.mapView.removeAnnotation(annotation)
}
localSearchRequest = MKLocalSearchRequest()
localSearchRequest.naturalLanguageQuery = searchBar.text
localSearch = MKLocalSearch(request: localSearchRequest)
localSearch.startWithCompletionHandler { (localSearchResponse, error) -> Void in
if localSearchResponse == nil{
let alertController = UIAlertController(title: nil, message: "No Such Place", preferredStyle: UIAlertControllerStyle.Alert)
alertController.addAction(UIAlertAction(title: "Dismiss", style: UIAlertActionStyle.Default, handler: nil))
self.presentViewController(alertController, animated: true, completion: nil)
return
}
self.pointAnnotation = MKPointAnnotation()
self.pointAnnotation.title = searchBar.text
self.pointAnnotation.coordinate = CLLocationCoordinate2D(latitude: localSearchResponse!.boundingRegion.center.latitude, longitude: localSearchResponse!.boundingRegion.center.longitude)
self.pinAnnotationView = MKPinAnnotationView(annotation: self.pointAnnotation, reuseIdentifier: nil)
self.mapView.centerCoordinate = self.pointAnnotation.coordinate
}
}
}
I am new to Swift so any help is really appreciated. Thanks!
Edit:
This is the error screen presented to me once the app crashes:
I haven't used mapKit but I still try.
Looking at your error your getting a nil crash, which indicates one of your properties is nil yet you try to use it.
Having a quick read through your code it seams you haven't initialised
var localSearchResponse....
Again i don't know the MK API very well so I am not 100 sure what I'm saying is relevant.
Have you checked that all your IBOutlets are properly connected?
On which line do you get the crash when this happens? Do you get the crash before or after changing to the abouts page?
I'm trying to make this posting app similar to instagram but I am getting stuck on a issue once i press my compose button. This button is suppose to post the image but instead its crashing. I'm having an error after I try to upload a caption\image with my app here:
let imageData = UIImagePNGRepresentation(imageToBeUploaded!)!
It is giving me this error:EXE_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
Please help!
#IBOutlet weak var captionTextView: UITextView!
#IBOutlet weak var previewImage: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
captionTextView.delegate = self
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func addImageTapped(sender: AnyObject) {
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
imagePicker.mediaTypes = UIImagePickerController.availableMediaTypesForSourceType(.PhotoLibrary)!
imagePicker.allowsEditing = false
self.presentViewController(imagePicker, animated: true, completion: nil)
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingImage image: UIImage!, editingInfo: [NSObject : AnyObject]!) {
self.previewImage.image = image
self.dismissViewControllerAnimated(true, completion: nil)
}
func textViewShouldEndEditing(textView: UITextView) -> Bool {
captionTextView.resignFirstResponder()
return true;
}
#IBAction func composeTapped(sender: AnyObject) {
let date = NSDate()
let dateFormatter = NSDateFormatter()
dateFormatter.timeStyle = NSDateFormatterStyle.ShortStyle
dateFormatter.dateStyle = NSDateFormatterStyle.ShortStyle
let localDate = dateFormatter.stringFromDate(date)
let imageToBeUploaded = self.previewImage.image
let imageData = UIImagePNGRepresentation(imageToBeUploaded!)!
let file: PFFile = PFFile(data: imageData)!
let fileCaption: String = self.captionTextView.text
let photoToUpload = PFObject(className: "Posts")
photoToUpload["Image"] = file
photoToUpload["Caption"] = fileCaption
photoToUpload["addedBy"] = PFUser.currentUser()?.username
photoToUpload["data"] = localDate
//Get bytes size of image
/* var imageSize = Float(imageData!.length)
//Transform into Megabytes
imageSize = imageSize/(1024*1024)
print("Image size is \(imageSize)Mb")
*/
do{
try photoToUpload.save()
} catch _ {
}
print("Successfully Posted.")
let vc = self.storyboard?.instantiateViewControllerWithIdentifier("postController")
self.presentViewController(vc! as UIViewController, animated: true, completion: nil)
}
It seems that you are unwraping an optional value without actualy checking if it is nil.
Probably the issue is from let file: PFFile = PFFile(data: imageData)!. You must check for nil before you unwrap a variable.
I have an app that has two ViewControllers. On the first there is a count of current speed in realtime through CLLocationManager. Also there is a label that shows current speed with update by timer (NSTimer). In second ViewController there is another Label, where this current speed has to be shown too. It shows it, but don't update. I tried to set second timer (different ways: in first VC, in second VC - there is always was an error or just nothing).
Will be grateful for help, thanks!
First VC
import UIKit
import MapKit
import CoreLocation
class ViewController: UIViewController, CLLocationManagerDelegate {
#IBOutlet weak var mapView: MKMapView!
#IBOutlet weak var currentSpeedLabel: UILabel!
var manager = CLLocationManager()
var currentSpeed: CLLocationSpeed = CLLocationSpeed()
var timer = NSTimer()
override func viewDidLoad() {
super.viewDidLoad()
mapView.mapType = MKMapType.Hybrid
trackingMe()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
#IBAction func HUDMapView(sender: AnyObject) {
speedCount()
}
#IBAction func findMe(sender: AnyObject) {
trackingMe()
}
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let userLocation: CLLocation = locations[0] as CLLocation
manager.stopUpdatingLocation()
let location = CLLocationCoordinate2D(latitude: userLocation.coordinate.latitude, longitude: userLocation.coordinate.longitude)
let span = MKCoordinateSpanMake(0.05, 0.05)
let region = MKCoordinateRegion(center: location, span: span)
mapView.setRegion(region, animated: true)
}
func trackingMe() {
manager.delegate = self
manager.desiredAccuracy = kCLLocationAccuracyBest
manager.requestWhenInUseAuthorization()
manager.startUpdatingLocation()
mapView.showsUserLocation = true
currentSpeedUpdate()
}
func currentSpeedUpdate() {
timer = NSTimer.scheduledTimerWithTimeInterval(0.5, target: self, selector: Selector("speedCount"), userInfo: nil, repeats: true)
}
func speedCount() {
currentSpeed = manager.location!.speed
currentSpeedLabel.text = String(format: "%.0f km/h", currentSpeed * 3.6)
}
override func prepareForSegue(segue: (UIStoryboardSegue!), sender: AnyObject!) {
let speedController = segue.destinationViewController as! speedViewController
currentSpeed = manager.location!.speed
speedController.showSpeed = currentSpeedLabel.text
}
}
Second VC
import UIKit
class speedViewController: UIViewController {
#IBOutlet weak var secondSpeedLabel: UILabel!
var showSpeed: String!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
secondSpeedLabel.text = showSpeed
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func back(sender: AnyObject) {
self.dismissViewControllerAnimated(true, completion: nil)
}
}
Project Link
You could use a Singleton to hold the LocationManager. Then you can access it from all over your app. When you move to a second VC you can either change the delegate to the second VC or just get the needed data manually.
Remember that a delegate can only point to one "receiver". Changing the delegate will stop updates in the first VC. but since it is now a Singleton you can also store information in there about past locations / speeds. When dismissing the second VC get the stored data and update.
This will keep running until you call stop()
The code was simplified a bit to illustrate the idea.
VC Code:
import UIKit
import CoreLocation
class ViewController: UIViewController, TrackerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
Tracker.shared.delegate = self
Tracker.shared.start()
}
func speedUpdate(speed: CLLocationSpeed) {
print(speed)
}
}
Singleton Code:
import UIKit
import MapKit
import CoreLocation
class Tracker: NSObject, CLLocationManagerDelegate {
static var shared = Tracker()
private var manager = CLLocationManager()
private var timer = NSTimer()
var region : MKCoordinateRegion?
var currentSpeed: CLLocationSpeed = CLLocationSpeed()
weak var delegate : TrackerDelegate?
private override init() {
super.init()
manager.delegate = self
manager.requestWhenInUseAuthorization()
}
internal func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
manager.stopUpdatingLocation()
let userLocation: CLLocation = locations[0] as CLLocation
let coordinates2D = CLLocationCoordinate2D(latitude: userLocation.coordinate.latitude, longitude: userLocation.coordinate.longitude)
let span = MKCoordinateSpanMake(0.05, 0.05)
region = MKCoordinateRegion(center: coordinates2D, span: span)
currentSpeed = userLocation.speed
guard let del = delegate else {
return
}
del.speedUpdate(currentSpeed)
}
func start() {
manager.desiredAccuracy = kCLLocationAccuracyBest
manager.startUpdatingLocation()
timer = NSTimer.scheduledTimerWithTimeInterval(0.5, target: self, selector: Selector("loopUpdate"), userInfo: nil, repeats: true)
}
func stop() {
timer.invalidate()
}
internal func loopUpdate() {
// restart updating
manager.startUpdatingLocation()
}
}
Delegate for the Singleton:
Add more functions, or more values to the current function to get more feedback.
protocol TrackerDelegate : class {
func speedUpdate(speed:CLLocationSpeed)
}
I recently updated to xCode 7 which uses iOS 9 and when I run the following app, the location is supposed to print to the console but that's not happening.
The app will build successfully, the map displays, but the location data doesn't print. Even if the move the map, it still doesn't print.
The code should be correct, i've imported all of the necessary frameworks and set both the NSLocationWhenInUseUsageDescription & NSLocationAlwaysUsageDescription in the Info.plist file along w/ their values.
Below is the code:
// ViewController.swift
// Maps iOS9
//
// Created by Alex Ngounou on 9/28/15.
// Copyright © 2015 Alex Ngounou. All rights reserved.
import UIKit
import MapKit
import CoreLocation
class ViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {
#IBOutlet weak var myMap: MKMapView!
var locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestAlwaysAuthorization()
locationManager.startUpdatingLocation() // starts accessing the user's position
// 18.328278, -65.318353 Playa Flamenco
let latitude: CLLocationDegrees = 18.328278
let longitude: CLLocationDegrees = -65.318353
let latDelta: CLLocationDegrees = 0.01
let longDelta: CLLocationDegrees = 0.01
let location: CLLocationCoordinate2D = CLLocationCoordinate2DMake(latitude, longitude)
let span: MKCoordinateSpan = MKCoordinateSpanMake(latDelta, longDelta)
let region: MKCoordinateRegion = MKCoordinateRegionMake(location, span)
myMap.setRegion(region, animated: true)
let annotation = MKPointAnnotation()
annotation.coordinate = location
annotation.title = "Playa de Flamenco"
annotation.subtitle = "Culebra Island"
myMap.addAnnotation(annotation)
let uilpgr = UILongPressGestureRecognizer(target: self, action: "action:")
uilpgr.minimumPressDuration = 1.0
myMap.addGestureRecognizer(uilpgr)
}
func action(gestureRecognizer: UILongPressGestureRecognizer) {
// touchpoint
let touchPoint = gestureRecognizer.locationInView(self.myMap)
// touchpoint to location
let newLocation: CLLocationCoordinate2D = myMap.convertPoint(touchPoint, toCoordinateFromView: self.myMap)
// annotation
let newAnnotation = MKPointAnnotation()
newAnnotation.coordinate = newLocation
newAnnotation.title = "New Poing"
newAnnotation.subtitle = "added via user's touch"
myMap.addAnnotation(newAnnotation)
}
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
print(locations)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Try this code snippet:
// Location Manager helper stuff
func initLocationManager() {
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.locationServicesEnabled
locationManager.requestAlwaysAuthorization()
}
// Location Manager Delegate stuff
// If failed
func locationManager(manager: CLLocationManager!, didFailWithError error: NSError!) {
locationManager.stopUpdatingLocation()
if (error) {
print(error)
}
}
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: AnyObject[]!) {
println("locations = \(locations)")
}
// authorization status
func locationManager(manager: CLLocationManager!,
didChangeAuthorizationStatus status: CLAuthorizationStatus) {
var shouldIAllow = false
switch status {
case CLAuthorizationStatus.Restricted:
locationStatus = "Restricted Access to location"
case CLAuthorizationStatus.Denied:
locationStatus = "User denied access to location"
case CLAuthorizationStatus.NotDetermined:
locationStatus = "Status not determined"
default:
locationStatus = "Allowed to location Access"
shouldIAllow = true
}
NSNotificationCenter.defaultCenter().postNotificationName("LabelHasbeenUpdated", object: nil)
if (shouldIAllow == true) {
NSLog("Location to Allowed")
// Start location services
locationManager.startUpdatingLocation()
} else {
NSLog("Denied access: \(locationStatus)")
}
}
The "Debug/Location" of my iOS simulator wasn't set correctly. Once I changed this to "City Bicycle Ride", everything's good!
Thanks for the help!
I am new to swift and I have an app which allows the user to get a picture from their camera roll and display it in an imageview. I have found plenty of tutorials on how to add filters, but how do I isolate this to a touch radius, not the entire image?
import UIKit
import AVFoundation
import Social
import MobileCoreServices
import MessageUI
import iAd
class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate, UIAlertViewDelegate, UITextFieldDelegate, UITextViewDelegate {
#IBOutlet var imageView: UIImageView!
let picker = UIImagePickerController()
var cameraUI: UIImagePickerController! = UIImagePickerController()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
#IBAction func filter(sender: UIButton) {
let myPicture = imageView.image
let filter = CIFilter(name: "CIPhotoEffectMono")
filter.setValue(CIImage(image: myPicture), forKey: kCIInputImageKey)
let newImage = UIImage(CIImage: filter.outputImage)
imageView.image = newImage
}
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
let myPicture = imageView.image
for obj in touches {
let touch = obj as! UITouch
let location = touch.locationInView(self.view)
}
}
#IBAction func getImageButton(sender: UIButton) {
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.PhotoLibrary)
{
cameraUI = UIImagePickerController()
cameraUI.delegate = self
cameraUI.sourceType = UIImagePickerControllerSourceType.PhotoLibrary;
cameraUI.mediaTypes = [kUTTypeImage]
cameraUI.allowsEditing = false
self.presentViewController(cameraUI, animated: true, completion: nil)
}
else
{
let alertVC = UIAlertController(title: "Error", message: "Cannot open camera roll.", preferredStyle: .Alert)
let okAction = UIAlertAction(title: "OK", style:.Default, handler: nil)
alertVC.addAction(okAction)
presentViewController(alertVC, animated: true, completion: nil)
}
}
func imagePickerControllerDidCancel(picker: UIImagePickerController) {
dismissViewControllerAnimated(true, completion: nil)
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]) {
var chosenImage = info[UIImagePickerControllerOriginalImage] as! UIImage //2
imageView.contentMode = .ScaleAspectFit //3
imageView.image = chosenImage //4
dismissViewControllerAnimated(true, completion: nil) //5
}
func noCamera(){
let alertVC = UIAlertController(title: "No Camera", message: "Sorry, this device has no camera", preferredStyle: .Alert)
let okAction = UIAlertAction(title: "OK", style:.Default, handler: nil)
alertVC.addAction(okAction)
presentViewController(alertVC, animated: true, completion: nil)
}
func savedImageAlert()
{
var alert:UIAlertView = UIAlertView()
alert.title = "Saved!"
alert.message = "Your picture was saved"
alert.delegate = self
alert.addButtonWithTitle("Ok")
alert.show()
}
}