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

Posted

技术标签:

【中文标题】快速,在后台检测 ibeacons 并在范围内发送通知【英文标题】:swift, detect ibeacons on the background and send notifications when in range 【发布时间】:2018-10-17 13:09:10 【问题描述】:

您好,我是 IBeacons 的新手,也是 swift 的初学者,我正在尝试制作一个小应用程序,可以在应用程序的后台检测 Ibeacon 并在 Ibeacon 在范围内时发送通知我设法这样做但只有当我在应用程序打开时走路时,我无法使其工作并在后台搜索 Ibeacons,即使我允许应用程序访问以使用后台获取位置

 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】:

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

locationManager.requestAlwaysAuthorization() 只会解锁在后台使用信标监控的能力。当信标首次出现 (didEnter(region: region)) 或全部消失 (didExit(region: region)) 时,信标监控会给您一个单一的呼叫。 这是正常情况下唯一在后台工作的信标 API。

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

    按照我的博文here 中的描述,在应用程序转换到后台后,您可以通过启动后台任务来获得 180 秒的后台测距。

    你也可以告诉 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") 

【讨论】:

非常感谢,这对我帮助很大,我真的很感激

以上是关于快速,在后台检测 ibeacons 并在范围内发送通知的主要内容,如果未能解决你的问题,请参考以下文章

如何查找 iBeacon 范围内的设备数量?

设置范围区域 iBeacons

iBeacon /发送者/接收者如何处理冲突?

IOS:iBeacon 检测后可用的操作

iBeacon 监控无法正常工作

iBeacon:何时向服务器发送信标事件