0

TLDR - Goal: Build a simple compass app

I'm brand new at coding and I'm challenging myself to try and learn something new. I've studied up on the main components of coding and followed a few simple tutorials. I've also been learning a lot on here.

However, I'm still having a hard time understanding how to retrieve the magnetometer data. I've read the Apple documentation in Obj-C and Swift (with Swift being new, compass tutorials are almost exclusively done in Obj-C), but they are still confusing, to someone who is as new as I am, when trying to convert that over to swift.

I've looked up similar questions and even tried to run the code from them and I usually get at least 1 error saying something is expected or missing or not defined. Preventing me from even testing it... Which has led me down a long road of trying to understand Xcode's error syntax.

I know I have to test on my device, otherwise I won't see any data. I also know I have to import CoreMotion, then use CMMotionManager as sort of a 'gateway' to retrieving the data, and then define the update intervals. But I'm unclear on how to go about structuring that part of code that actually does the retrieving of the data.

In short I just want to have the barebones simplest route to retrieving the data and have it print while I move my phone. Dumbed down explanations of the process are welcome. I promise I won't be offended, in fact I'd be delighted.

Anyone in a teaching mood?

KeeperOfKale
  • 711
  • 1
  • 7
  • 10

2 Answers2

1

If you want to build a simple compass app, I recommend you start by using CLLocationManager instead of CMMotionManager. You implement locationManager(didUpdateHeading:) method of CLLocationManagerDelegate (docs). In addition, you create a CLLocationManager (docs) and start heading updates for example in viewDidLoad You can do it for example in your view controller, that XCode creates for you:

class MyViewController: UIViewController, CLLocationManagerDelegate {
     var locationManager: CLLocationManager!

     override func viewDidLoad() {
         super.viewDidLoad()
         locationManager = CLLocationManager()
         locationManager.delegate = self
         locationManager.startHeadingUpdates()
     }


     override func locationManager(_ manager: CLLocationManager!,
                 didUpdateHeading newHeading: CLHeading!) {
          println("New heading \(newHeading.magneticHeading)")
          // TODO: update your UIViews that draw the compass here.             
     }
}

This gets you started, but for the real application, you might want to start and stop heading updates in viewWillAppear and viewDidDisappear methods.

Teemu Kurppa
  • 4,779
  • 2
  • 32
  • 38
  • I'm getting error " 'CLLocationManager' does not have a member named 'startHeadingUpdates' " – KeeperOfKale Feb 28 '15 at 00:21
  • I've used startUpdatingHeading. I've used your code so far and receive no errors, but also no outputs either. Is update interval needed? – KeeperOfKale Feb 28 '15 at 00:35
  • I am also trying to do this, and not getting any updates. I also am trying to capture the other location information, and I thought it was because I was trying to do both. But I guess not, given that this isn't working for you. I am now suspecting that it has something to do with calibration. – nroose Mar 23 '15 at 05:38
1

You need to be sure your app has properly asked for permission and the plist is properly set up

code snippet:

    // don't forget iOS 8 wants the plist value too!
    if (locationManager.respondsToSelector(Selector("requestWhenInUseAuthorization"))) {
        locationManager.requestWhenInUseAuthorization()
    }
julie m
  • 11
  • 1