IOS iBeacons

原文鏈接http://www.lanou3g.com/news_show.php?id=478

如何使用iOS 7的iBeacons來提高你的應用

發佈時間:2014-01-16   來源:藍鷗3G學院-ios培訓-蘋果中國ios開發者 高端實訓基地

iBeacons是蘋果在WWDC 2013上有意無意透漏出來的一項重要功能,通過低功耗藍牙(BluetoothLowEnergy)技術進行十分精確的微定位和室內導航,據悉其定位精度可以以釐米計算。

 

實現iBeacons精準的微定位功能除了需要運行iOS 7且支持BLE的設備外,還需要在室內、店內或者其他公共環境中部署iBeacon基站。當用戶走進信號覆蓋區域內時,用戶就會收到相關的提醒和詢問。以梅西百貨爲例,當用戶走到商場某個店面附近時,安裝了相應app的用戶就會收到由iBeacons基站發出的產品信息或者打折信息。此外,美國職棒大聯盟(MLB)也已經測試使用了iBeacon 技術,蘋果更是在254間Apple Store 裏應用了iBeacon 技術。

 

對於開發者來說,可以創建一個更加具有交互性的博物館應用,當用戶在博物館內隨意行走時,通過信息提醒用戶某些特別的展覽。技術還可以用作室內導航,比如在地鐵站或者機場這些GPS信號不大好的地方更好地引導用戶。

 

文章目的有兩個,一是理解iBeacons,二是展示如何在app中使用iBeacons。

 

Demo

文中所用的demo是我們用來展示如何檢測和處理來自beacon的廣播,但首先我們需要創建另外一款app來擔當beacon的角色--沒有其他功能,只是用來廣播信號。最後,我們將有代表雙方溝通的兩款app。

 

注意:iBeacons是iOS 7引入的新技術,所以我們需要兩部運行iOS 7並支持BLE的設備,比如iPhone 4S以上設備,iPad mini以及iPad 3以後設備。同時,爲了在設備上部署app,你還需要是蘋果iOS開發者計劃(99美元)成員。

 

設置:Broadcasting App

beacon廣播的是什麼?它是一個UUID,類似:C293726B-63BF-420A-9D79-92C71F67536A。beacon會不斷地廣播該UUID,並且接收方app會用同樣的UUID檢測信號。



首先在Xcode中創建一個新的Single View Application,

 

 

點擊下一步,並給項目命名,你可以輸入“AppCoda”作爲組織名稱,把“com.appcoda”作爲bundle identifier:

 

 

下一步爲開啓廣播的按鈕添加圖片。



打開圖片資產庫(images.xcassets),找到資產列表,右鍵點擊並選擇“New Image Set”。

 

 

給圖片重新命名爲“BroadcastButton”。選擇圖片後,你會看到兩個spot,一個是用來添加2x圖片,一個是用來添加1x圖片。

 

 

把兩個按鈕圖片保存至文件系統,並把“[email protected]”和“BroadcastBtn.png”分別拖至2x spot和1x spot.

 

 

在Main.storyboard中,爲了添加一個UIButton按鈕,我們需要把其中一個從右下角的Objects pane中拖至視圖上。

 

 

在storyboard中選擇按鈕,並找到屬性面板,取消標題,並把圖片改爲我們之前添加的那個。

 

 

把按鈕放置在視圖中間,如下圖:

 

 

現在,在視圖中添加UILabel元素,這樣我們就知道app什麼時候廣播。從Objects pane中把一個UILabel元素拖至視圖上。然後,查看尺寸屬性,並把它設置爲居中對齊,寬度爲200。讓它在你的視圖中居中對齊,如下圖:

 

接下來,通過IBOutlet屬性連接把這個UILabel 添加到viewcontroller對象上。打開輔助編輯器(你也可以使用Xcode interface右上角的幫助編輯器按鈕來做這些)。

 

確定右窗格中展示的是ViewController.h,然後按着control鍵,點擊uilabel、拖動一條線放到“@interface” 和“@end”行之間。

 

鬆開鼠標,出現一個彈出對話框,給屬性指定一個名稱--“statusLabel”.

 

ViewController.h文件應該是這樣的:

@interface ViewController : UIViewController 

  

@property (strong, nonatomic) IBOutlet UILabel *statusLabel; 

  

@end 

現在把廣播按鈕連接至IBAction method handler。在輔助編輯器中,把右面板改爲ViewController.m。按住control鍵,從UIButton拖出一條線放在.m 文件中的“@implementation” 和 “@end”行中間。在彈出對話框中,爲該方法命名爲“buttonClicked”

 

 

 

ViewController.m 文件在結束時會有這個方法:

- (IBAction)buttonClicked:(id)sender {  

 

添加需要的框架

在通過Bluetooth進行實際廣播前,我們需要爲項目添加適當的框架。

 

打開項目設置,滾動至底部。在“Linked Frameworks and Libraries”下點擊“+”按鈕添加CoreBluetooth.framework和CoreLocation.framework.

 

 

 

 

創建一個UUID

在Mac上打開Launchpad(或者僅打開應用程序文件夾),並打開Terminal app。在Launchpad中,它可能是一個被叫做“Other”的文件夾,圖標如下圖:

 

 

打開後,你會看見一個可以鍵入“uuidgen”的窗口,它會輸出一個可供使用的UUID!複製生成的UUID,我們將會用它進行廣播。

 

Beacon廣播

在ViewController.h中,我們要輸入先前添加的框架。

#import <CoreLocation/CoreLocation.h> 

#import <CoreBluetooth/CoreBluetooth.h> 

 

下一步,添加用以廣播的3個以上屬性,這樣你在ViewController.h file中會有4個屬性。

@property (weak, nonatomic) IBOutlet UILabel *statusLabel; 

@property (strong, nonatomic) CLBeaconRegion *myBeaconRegion; 

@property (strong, nonatomic) NSDictionary *myBeaconData; 

@property (strong, nonatomic) CBPeripheralManager *peripheralManager; 

 

這裏還有一件事要完成--讓ViewController類遵循“CBPeripheralManagerDelegate”協議,我們可以在class declaration中添加如下代碼

@interface ViewController : UIViewController<CBPeripheralManagerDelegate> 

.h file完成後,打開.m file,

 

在viewDidLoad方法中添加如下代碼(替代我們之前生成的UUID)

- (void)viewDidLoad 

    [super viewDidLoad]; 

    // Do any additional setup after loading the view, typically from a nib. 

     

    // Create a NSUUID object 

    NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:@"A77A1B68-49A7-4DBF-914C-760D07FBB87B"]; 

     

    // Initialize the Beacon Region 

    self.myBeaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid 

                                                                  major:1 

                                                                  minor:1 

                                                             identifier:@"com.appcoda.testregion"]; 

在上邊的代碼中,我們創建了一個新的NSUUID對象。

 

然後,我們設置了一個CLBeaconRegion,並通過那個UUID進行初始化,major number,minor number 以及identifier。如果你所處的位置內有一大堆數據,major number和minor number就是用來識別你的beacons。在上邊梅西百貨的例子中,每個department會有一個特定的major number--識別一組beacons,在店內,每個beacon會有一個特定的minor number。

 

通過major number和minor number ,你將能精確識別哪個beacon被獲取了。最後,標識符是該區域唯一的ID。

 

在之前我們設置的buttonClicked method中,我們添加如下代碼:

- (IBAction)buttonClicked:(id)sender { 

     

    // Get the beacon data to advertise 

    self.myBeaconData = [self.myBeaconRegion peripheralDataWithMeasuredPower:nil]; 

     

    // Start the peripheral manager 

    self.peripheralManager = [[CBPeripheralManager alloc] initWithDelegate:self 

                                                                     queue:nil 

                                                                   options:nil]; 

在上述代碼中,我們調用了“peripheralDataWithMeasuredPower:” ,它可以給我們提供即將進行廣播的beacon data。

 

第二行代碼啓動了外圍設備管理,並監控Bluetooth的狀態更新。

 

現在我們需要處理狀態更新方法來檢測Bluetooth何時打開和關閉。所以添加以下委託方法,因爲我們的ViewController類遵照“CBPeripheralManagerDelegate” protocol。

-(void)peripheralManagerDidUpdateState:(CBPeripheralManager*)peripheral 

    if (peripheral.state == CBPeripheralManagerStatePoweredOn) 

    { 

        // Bluetooth is on 

         

        // Update our status label 

        self.statusLabel.text = @"Broadcasting..."; 

         

        // Start broadcasting 

        [self.peripheralManager startAdvertising:self.myBeaconData]; 

    } 

    else if (peripheral.state == CBPeripheralManagerStatePoweredOff) 

    { 

        // Update our status label 

        self.statusLabel.text = @"Stopped"; 

當Bluetooth外圍設備狀態改變時會觸發該方法。所以在該方法中,我們要檢查當前設備處於什麼狀態。如果Bluetooth處於打開狀態,我們將會更新我們的標籤,調用“startAdvertising”方法,並把傳遞beacon data進行廣播。相反,如果Bluetooth處於關閉狀態,我們將會停止廣播。

 

現在把app部署至設備,打開Bluetooth並點擊按鈕,系統就會廣播你的UUID!現在我們要創建一個接收方的app來檢測和處理廣播。

 

注意:模擬器不能使用Bluetooth,所以不能通過模擬器進行廣播。爲了把app部署至支持BLE的真實設備上(iPhone 4S and up, iPad mini and iPad 3 and up),你需要加入蘋果開發者計劃。

 

 

 

檢測Beacon

設置另一個Single View Application,並命名爲“BeaconReceiver”

 

 

打開Main.storyboard,在view中添加單個UILabel,當檢測到用來更新狀態--當檢測到detected時。從 Objects pane中拖放一個UILable元素至你的視圖中。然後點擊UILable,打開屬性面板改爲居中對齊,並把寬度改爲200,如下圖:

 

 

添加CoreLocation框架

CoreLocation框架已經更新以支持beacon檢測,我們需要把它添加在我們項目中。打開項目屬性並點擊“Linked Libraries and Frameworks”下的“+”圖標。添加CoreLocation框架

 

 

現在,像之前那樣,通過IBOutlet屬性連接來添加UILabel。打開輔助編輯器,確保ViewController.h位於右邊窗格。按下“control”鍵並點擊UILabel,拖出一條線並放在 “@interface” 和 “@end”行之間。放開後,出現一個彈出對話框,你可以給屬性命名爲“statusLabel”。

 

 

 

@interface ViewController : UIViewController 

  

@property (weak, nonatomic) IBOutlet UILabel *statusLabel; 

  

@end 

 

最後打開ViewController.h,在文件頂部添加該框架,並調整類聲明使之遵從CLLocationManagerDelegate協議,該協議包含一個delegate method,可以讓我們知道最新監測到的beacons。

#import <UIKit/UIKit.h> 

#import <CoreLocation/CoreLocation.h> 

  

@interface ViewController : UIViewController<CLLocationManagerDelegate> 

  

@property (weak, nonatomic) IBOutlet UILabel *statusLabel; 

  

@end 

 

監測Beacons

我們需要添加兩個屬性,一個是保持對beacon region(我們即將進行檢測)的跟蹤;另一個是保存locationmanager,它會更新發現的beacons,在ViewController.h添加以下代碼:

@interface ViewController : UIViewController<CLLocationManagerDelegate> 

  

@property (strong, nonatomic) CLBeaconRegion *myBeaconRegion; 

@property (strong, nonatomic) CLLocationManager *locationManager; 

@property (weak, nonatomic) IBOutlet UILabel *statusLabel; 

  

@end 

 

現在打開ViewController.m,在“viewDidLoad” 方法中,我們將要初始化locationManager,把我們設置爲它的委託。我們也將開始監控想要的beacon,so have that UUID handy!

- (void)viewDidLoad 

    [super viewDidLoad]; 

    // Do any additional setup after loading the view, typically from a nib. 

     

    // Initialize location manager and set ourselves as the delegate 

    self.locationManager = [[CLLocationManager alloc] init]; 

    self.locationManager.delegate = self; 

     

    // Create a NSUUID with the same UUID as the broadcasting beacon 

    NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:@"A77A1B68-49A7-4DBF-914C-760D07FBB87B"]; 

     

    // Setup a new region with that UUID and same identifier as the broadcasting beacon 

    self.myBeaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid 

                                                             identifier:@"com.appcoda.testregion"]; 

     

    // Tell location manager to start monitoring for the beacon region 

    [self.locationManager startMonitoringForRegion:self.myBeaconRegion]; 

 

在第7和第8行代碼中,我們把locationManager初始化爲CLLocationManager的新實例,然後把我們設置爲它的委託,這樣當更新時就會通知我們。

 

在11行中,我們通過同樣的UUID設置了NSUUID對象,作爲一個被app(先前創建的那個)廣播的對象。

 

最後我們把region傳遞給location manager 以便於監視。

 

下一步,我們需要執行一些委託方法,當region被檢測時將會調用該方法。

 

 首先,在ViewController.m中添加如下代碼:

- (void)locationManager:(CLLocationManager*)manager didEnterRegion:(CLRegion*)region  

    [self.locationManager startRangingBeaconsInRegion:self.beaconRegion]; 

  

-(void)locationManager:(CLLocationManager*)manager didExitRegion:(CLRegion*)region  

    [self.locationManager stopRangingBeaconsInRegion:self.beaconRegion]; 

    self.beaconFoundLabel.text = @"No"; 

上邊代碼執行了兩個方法,當設備進入區域或者離開區域時會被調用。當區域被檢測,我們通知locationManager開始尋找區域內的beacons。

 

現在執行這個方法

-(void)locationManager:(CLLocationManager*)manager 

       didRangeBeacons:(NSArray*)beacons 

              inRegion:(CLBeaconRegion*)region 

    // Beacon found! 

    self.statusLabel.text = @"Beacon found!"; 

     

    CLBeacon *foundBeacon = [beacons firstObject]; 

     

    // You can retrieve the beacon data from its properties 

    //NSString *uuid = foundBeacon.proximityUUID.UUIDString; 

    //NSString *major = [NSString stringWithFormat:@"%@", foundBeacon.major]; 

    //NSString *minor = [NSString stringWithFormat:@"%@", foundBeacon.minor]; 

當一個或者更多beacons被檢測時,該方法將會被失效。在上述代碼中,你可以看到我們如何獲得UUID,來自beacon的major和minor數據。另外,雖然我們上邊並未執行,但你可以遍歷beacons array,並通過檢測近距離的beacon屬性來決定哪一個是最近的。

 

運行demo

如果你有兩臺iOS真機,並且你已經加入了蘋果iOS開發者計劃,那你就可以對該技術進行測試。發佈beacon app和點擊“Broadcast”按鈕,然後等待“Broadcasting…”信息出現。發佈receiver app,並讓它遠離broadcasting beacon,然後走近它模仿實際進入beacon區域。

 

 

總結

如果你沒有多臺設備,你可以通過購買BLE beacons並把他們放在房子周圍來創建很酷的app。 Estimote makes such beacons and you get three for $99.

 

所以我希望你能明白iBeacons應用的強大之處,我也希望這個demo能點燃你對真實世界的想象。你可以下載在此下載demo app的Xcode項目。

發佈了56 篇原創文章 · 獲贊 4 · 訪問量 21萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章