快速,在后台检测ibeacons并在范围内发送通知

时间:2018-10-17 13:09:10

标签: swift ibeacon

您好,我是IBeacons的新手,也是swift的初学者,我正在尝试制作一个小型应用程序,该应用程序可在应用程序的背景下检测到Ibeacon,并在Ibeacon处于有效范围内时发送通知,但当我在应用程序打开时行走时,即使我使用了

来授予应用程序访问背景位置的权限,我也无法使其正常工作并在后台搜索Ibeacon。
 if (CLLocationManager.authorizationStatus() != CLAuthorizationStatus.authorizedAlways) {
        locationManager.requestAlwaysAuthorization();
    }

这是我的主要问题,我也有一个副问题,如果关闭并再次打开该应用程序,则该应用程序不会保存该人的姓名。这是我的代码,非常感谢您的帮助,如果您有任何参考以了解有关IBeacons应用程序的更多信息,我将不胜感激

   import UIKit
   import CoreLocation
   import UserNotifications

   class ViewController: UIViewController, CLLocationManagerDelegate {
   @IBOutlet weak var field: UITextField!
   @IBOutlet weak var textLbl : UILabel!
   var inRoom = false
   var name = ""
   var sendYet = false ;

func sendHiNoti()
{
    name = field.text! ;
    let content = UNMutableNotificationContent()
    content.title = "Heloo "+name
    content.subtitle = "Welcome to your Home"
    content.body = "this messaage to welcome you in Home"
    content.badge = 1
    content.sound = UNNotificationSound(named: UNNotificationSoundName(rawValue: "quiteimpressed.mp3"))
    let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 2, repeats: false)
    let request = UNNotificationRequest(identifier: "azanSoon", content: content, trigger: trigger)
    UNUserNotificationCenter.current().removeAllPendingNotificationRequests()
    UNUserNotificationCenter.current().add(request) {(error) in
        if let error = error {
            print("error: \(error)")
        }
    }
}

func sendByeNoti()
{
    name = field.text! ;
    let content = UNMutableNotificationContent()
    content.title = "OH"+name
    content.subtitle = "You are going out already ??"
    content.body = "Take care of your self"
    content.badge = 1
    content.sound = UNNotificationSound(named: UNNotificationSoundName(rawValue: "quiteimpressed.mp3"))
    let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 2, repeats: false)
    let request = UNNotificationRequest(identifier: "azanSoon", content: content, trigger: trigger)
    UNUserNotificationCenter.current().removeAllPendingNotificationRequests()
    UNUserNotificationCenter.current().add(request) {(error) in
        if let error = error {
            print("error: \(error)")
        }
    }
}

@IBAction func getText(){
    name = field.text!
    let alert = UIAlertController(title: "Your Name is", message: name, preferredStyle: UIAlertController.Style.alert)
    alert.addAction(UIAlertAction(title: "Ok", style: UIAlertAction.Style.default, handler: nil))
    self.present(alert, animated: true, completion: nil)

}


var locationManager = CLLocationManager()

override func viewDidLoad() {

    super.viewDidLoad()

    locationManager.delegate = self


    UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge], completionHandler: {didAllow, error in})

    let uuid = UUID(uuidString: "E2C56DB5-DFFB-48D2-B060-D0F5A71096E0")!
    let beaconRegion = CLBeaconRegion(proximityUUID: uuid, major: 444, minor: 333, identifier: "abcdefac005b")

    if (CLLocationManager.authorizationStatus() != CLAuthorizationStatus.authorizedAlways) {
        locationManager.requestAlwaysAuthorization();
    }
    locationManager.startRangingBeacons(in: beaconRegion)
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()

}



func locationManager(_ manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], in region: CLBeaconRegion) {
    print(beacons)
    if(beacons.count > 0){
    if(!sendYet){
    if beacons[0].proximity.rawValue < 2 {
        textLbl.text = "In the room"
        sendHiNoti()
        sendYet = true ;
    }
    }
   else if beacons[0].proximity.rawValue >= 3 {
        textLbl.text = "Outside the room"
        sendByeNoti()
        sendYet = false ;
    }
}
}
}

1 个答案:

答案 0 :(得分:0)

所示代码使用范围为locationManager.startRangingBeacons(in: beaconRegion)的信标,通常在前景和背景之间转换后超过10秒钟在后台不支持该信标。

locationManager.requestAlwaysAuthorization()仅在后台解锁使用信标监视的功能。当信标第一次出现(didEnter(region: region))或全部消失(didExit(region: region))时,信标监视将为您提供一个呼叫。 在正常情况下,这是唯一在后台运行的信标API。

可以使用两种技术在后台进行信标测距超过10秒:

  1. 如我的博客文章here中所述,通过启动后台任务,您可以在应用转换到后台后获得180秒的后台测距。

  2. 您还可以告诉iOS,您是一个定位应用,可以解锁无限的背景信标范围。您必须首先在第1部分中实现该解决方案。然后,在Info.plist中声明:

    <key>UIBackgroundModes</key>
    <array>
        <string>location</string>
    </array>
    

    最后,在您的代码中运行locationManager.startUpdatingLocation()。这将使您的应用收到其纬度/经度的定期更新,但是副作用是,您可以使步骤1中的后台任务永远运行,从而允许范围在后台永远继续。

如果您选择使用选项2,请注意,要使您的应用在AppStore中获得批准出售会更加困难。您必须说服Apple评论者,使您的应用程序是合法的位置应用程序(例如Waze或Apple Maps),并且用户知道您的应用程序始终在后台运行。如果您不相信他们,他们将拒绝您的应用。

另外,很容易将值保存到持久性存储中,以便在应用程序重新启动时保留它们。像这样使用NSUserDefaults:

 // save off name when user fills it in
 UserDefaults.standard.set(name, forKey: "name")

 // load back name on app restart
 name = UserDefaults.standard.string(forKey: "name")