Search code examples
swiftlocationibeacon

Swift - Get iBeacon - external class


I have built a class that should receive ibeacons. As far as I know, I'm doing everything right. But it doesn't work. My App doesn't ask for location permissions and the location manager doesn't start updating. I have also set the attributes in the plist.

NSLocationWhenInUseUsageDescription

NSLocationAlwaysUsageDescription

It only works when I initialize everything right in the AppDelegate. As in the tutorial here.

http://ibeaconmodules.us/blogs/news/14702963-tutorial-swift-based-ibeacon-app-development-with-corelocation-on-apple-ios-7-8

But I want to outsource this Service to a class. I don't know what I'm doing wrong. I'm new with Swift, in Objective-C it has always worked. Can anyone help me?

Here The Code-

ViewController

import UIKit

class ViewController: UIViewController,BeaconServiceProtocolDelegate {

override func viewDidLoad() {
    super.viewDidLoad()

    //Set BackgroundImage and hide Navigationbar
    self.view.backgroundColor = UIColor(patternImage: UIImage(named:"bg"));
    self.navigationController?.navigationBar.hidden = true

     ////////////////////////create new Beacon Service which is looking for beacon which are given with the parameters
    var beaconAdvertiseService = BeaconService(parauuidString: "F0018B9B-7509-4C31-A905-1A27D39C003C",parabeaconIdentifier:"iBeaconTalentTeamAudi");
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()

}

//Notification if our service found a beacon
func sendLocalNotificationWithMessage(message: String!) {
    let notification:UILocalNotification = UILocalNotification()
    notification.alertBody = message
    UIApplication.sharedApplication().scheduleLocalNotification(notification)
}

//Delegate from BeaconService
func foundBeacon() {
    println("Found Beacon")
}

}

and of course the class - BeaconAdvertiseService

import Foundation
import CoreBluetooth
import CoreLocation

//BeaconService Delegate
protocol BeaconServiceProtocolDelegate
{
    func foundBeacon()
}


import Foundation
import CoreBluetooth
import CoreLocation

//BeaconService Delegate
protocol BeaconServiceProtocolDelegate
{
    func foundBeacon()
}

class BeaconService: NSObject, CLLocationManagerDelegate{

    let beaconServiceDelegate:BeaconServiceProtocolDelegate?

    let uuidString:String//UUID Beacon as String
    let beaconIdentifier:String//Identifier Beacon
    let beaconUUID:NSUUID//UUID Beacon
    let beaconRegion:CLBeaconRegion//Beacon Region
    let locationManager:CLLocationManager ////location manager

     ////////////////////////Init class (constructor) // Params UUID as String & and Identifier from beacon
    init(parauuidString:String,parabeaconIdentifier:String) {



        self.uuidString         = parauuidString
        self.beaconIdentifier   = parabeaconIdentifier
        self.beaconUUID         = NSUUID(UUIDString: self.uuidString)
        self.beaconRegion       = CLBeaconRegion(proximityUUID:self.beaconUUID,identifier: self.beaconIdentifier)
        self.locationManager         = CLLocationManager();


        super.init()
        self.initLocationMangager()

    }

    ////////////////////////Init location manager
    private func initLocationMangager()
    {
        println(self.locationManager)

        if(self.locationManager.respondsToSelector("requestAlwaysAuthorization")) {
            locationManager.requestAlwaysAuthorization()
        }

        self.locationManager.delegate = self
        self.locationManager.pausesLocationUpdatesAutomatically = false

        self.locationManager.startMonitoringForRegion(beaconRegion)
        self.locationManager.startRangingBeaconsInRegion(beaconRegion)
        self.locationManager.startUpdatingLocation()
    }


    //////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////
    ////////////////////////LocationManager Delegates
    //////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////

    ////////////////////////LocationManager didStartMonitoringForRegion
    func locationManager(manager: CLLocationManager!, didStartMonitoringForRegion region: CLRegion!) {
        manager.startRangingBeaconsInRegion(region as CLBeaconRegion)
        println("Did Start")
    }

    ////////////////////////LocationManager didEnterRegion
    func locationManager(manager: CLLocationManager!, didEnterRegion region: CLRegion!) {
        manager.startRangingBeaconsInRegion(region as CLBeaconRegion)
    }

    ////////////////////////LocationManager didRangeBeacons
    func locationManager(manager: CLLocationManager!, didRangeBeacons beacons: [AnyObject]!, inRegion region: CLBeaconRegion!) {

            var message:String = ""

            if(beacons.count > 0) {
                let nearestBeacon:CLBeacon = beacons[0] as CLBeacon

                switch nearestBeacon.proximity {
                case CLProximity.Far:
                    message = "Far"
                case CLProximity.Near:
                    message = "Near"
                case CLProximity.Immediate:
                    message = "Immediate"
                case CLProximity.Unknown:
                    return
                }
            } else {
                message = "No Beacons"
            }

            //Call BeaconServiceDelegate
            beaconServiceDelegate?.foundBeacon()
    }

    ////////////////////////LocationManager monitoringDidFailForRegion
    func locationManager(manager: CLLocationManager!, monitoringDidFailForRegion region: CLRegion!, withError error: NSError!) {
        println(error)
    }

    ////////////////////////LocationManager didExitRegion
    func locationManager(manager: CLLocationManager!, didExitRegion region: CLRegion!) {
        manager.stopRangingBeaconsInRegion(region as CLBeaconRegion)

    }

}

Solution

  • It looks like you are assigning your advertise service to a local variable at the end of your viewDidLoad. This instance will be destroyed at the end of this method (one line later ;))

    Please make sure to assign your advertiser to an instance variable or property and assign self (your viewcontroller) as a delegate to your advertiser.

    This should do the trick.