We've had a number of customers who want to use Apple's new programming languageSwiftto develop iBeacon applications,so we decided to develop a tutorial to make it easier to get up and running. Right Now,Swift,Xcode 6,and iOS 8 are all covered under Apple's developer program NDA. It is our understanding,however,that Apple Now supports the release of tutorials such as this,provided that they are limited to code samples and do not reveal screenshots of technology covered under NDA. We have screenshots for this tutorial and we'll release them as soon as the NDA status allows us to do so. In the meantime,we've tried to make it clear enough to follow along in this text-only format. If anything is unclear,feel free to start a discussion below in the comments.

If you've landed here by accident and would prefer to work in Objective-C,no problem. We havea very similar tutorialthat will walk you through building the same app,step-by-step in Objective-C.

If you need iBeacon hardware,take a look atour selection. We offer two different iBeacon transmitter modules,both with fast (same-day on orders placed before 3pm eastern time),free first-class shipping from brooklyn,NY to anywhere in the world! If you don't see what you need,drop us a line atsales@ibeaconmodules.us.

Once you have your hardware,be sure to visit theproduct pagesfor simple activation instructions before using your beacons for the first time.

If all this is over your head,but you still have an idea for using iBeacon technology,contact ourdevelopment teamfor information and pricing on custom application design and development services. Otherwise,let's get going!

First,you'll need to register for the iOS developer program and provision a device. Ourprevious tutorialcovers these initial steps,so if you need help,go check it out and come back here when you're ready to dive in.

You'll also need to download and install the Xcode 6 beta,which is available from theiOS Dev Centeronce you've registered with the iOS developer program.

Once you've got a device provisioned and Xcode 6 up and running,you're ready to create a new project!

Swift-based iBeacon Template Application Tutorial

You candownload the template project from GitHub,but sometimes it's more illuminating to walk through the steps yourself:

1. Create a Swift Project

From the File menu,select New->Project. Select IOS Application from the left menu,and Single View Application from the options on the right. Then click Next.

2. Configure Project Options

In the next dialog,configure a project name,organization name,and organization identifier. Be sure to select Swift as the language. We'll be using iPhone as the device.

3. Add the CoreLocation framework to the project

Click on the main project entry in the file browser. Then make sure the General tab is selected. Scroll to the bottom and click the + to add a Linked Framework. Then find CoreLocation.framework in the list,select it,and click the Add button.

While you're in the General settings,you might want to change the Deployment target to 7.0 if you want this app to run on older versions of iOS. 6.x and earlier won't work,because they don't have the necessary CoreLocation functionality and they are generally reported to not work with Swift.

4. Configure Background Capabilities

In order to perform background ranging and monitoring and receive notifications,your app needs to register its need to use Location updates and Bluetooth LE accessories in the background. To do this,click the main project entry in the file browser. Then select the Capabilities tab and find Background Modes. Turn the switch ON,and then check Location updates and Uses Bluetooth LE accessories.

5. Define a region to be monitored

For Now,we're going to set things up in the application:didFinishLaunchingWithOptions method in AppDelegate.swift. First,we need to import the CoreLocation header,and then we will set up a CLBeaconRegion with the UUID for our beacon(s). A UUID is just an identifier that identifies a beacon or set of beacons. Any beacons you buy from us will come with the same UUID,although you can reprogram this if you like. This tutorial assumes that you've left the UUID at its default setting. Beacons can also be differentiated by another pair of IDs,called major and minor,but we'll get to that at another time. You also need to define an identifier for the region. This will let you distinguish between sets of beacons should your application ever track more than one. For Now,the top part of your App Delegate implementation should look like this:

import UIKit
import CoreLocation

@UIApplicationMain
class AppDelegate: UIResponder,UIApplicationDelegate {
                            
    var window: UIWindow?


    func application(application: UIApplication,didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool {

        let uuidString = "EBEFD083-70A2-47C8-9837-E7B5634DF524"
        let beaconIdentifier = "iBeaconModules.us"
        let beaconUUID:NSUUID = NSUUID(UUIDString: uuidString)
        let beaconRegion:CLBeaconRegion = CLBeaconRegion(proximityUUID: beaconUUID,identifier: beaconIdentifier)
        
        return true
    }

6. Set up plist entry for LocationAlways

iOS 8 requires special permission for always-on location monitoring,which includes iBeacon ranging. You need to include a specific plist entry that enables iOS to tell the user why you want this permission.

In the file browser under Supporting Files,open Info.plist. Select the top row "information Property List". Click the small plus sign to Add a Row. Give it the key (in the left column)NSLocationAlwaysUsageDescription. Make sure the type is set to String,and then set its value to whatever string you'd like to use to inform the user when they are prompted for location permissions.

7. Set up CLLocationManager for foreground/background monitoring and ranging

Now we have a region defined,but it won't do anything until we tell the device to monitor it. To do this,we need to create an instance of CLLocationManager and tell it to start monitoring the region we just created. We also need to define a "delegate" which is an object that gets notified whenever something happens with the location manager. We'll just use the App Delegate for Now.

ottom:20px; color:rgb(85,we need to import CoreLocation headers. Then we need to tell the compiler that our AppDelegate class will implement the CLLocationManagerDelegate protocol,and declare a property to hold our CLLocationManager object so that it survives for the entire lifetime of the application. We declare it with a question mark at the end of the line because it optional. This is because it's empty when the AppDelegate object is created and gets created in the didFinishLaunchingWithOptions method. Because it's optional,we have to access it with an exclamation mark after its name when we use it,as shown in the code below.

Inside the didFinishLaunchingWithOptions method,we need to create the CLLocationManager instance. Then we need to request "Always" authorization for location information. This is a new method in iOS 8 so we'll first check to see if the CLLocationManager responds to the selector and only call it if it does.

Then we tell it to start monitoring the region,start ranging the beacons,and start updating location. All three of these are required to receive range information updates when the app is in the background. After this is all complete,the top of AppDelegate.swift should look like this:

 

8. Define what happens when the region is entered

The device is Now monitoring the beacon,but we still haven't told it what to do when it sees it. Because we set our App Delegate as the CLLocationManager instance's delegate back in the prevIoUs step,it's going to look for methods hereto call when varIoUs events happen. You can find a list of methods in theCLLocationManagerDelegate Protocol Reference.

locationManager:didRangeBeacons:inRegion: looks interesting. Let's tell it to do something. In Swift,delegate protocols are typically implemented as class extensions.

Let's write an extension with a method to send a local notification and then handle didRangeBeacons and notify the user of the current status of the nearest beacon. Add this to the bottom of AppDelegate.swift (at theverybottom,outside of the closing bracket for the existing class declaration):

extension AppDelegate: CLLocationManagerDelegate {
    func sendlocalnotificationWithMessage(message: String!) {
        let notification:UIlocalnotification = UIlocalnotification()
        notification.alertBody = message
        UIApplication.sharedApplication().schedulelocalnotification(notification)
    }
    
    func locationManager(manager: CLLocationManager!,didRangeBeacons beacons: AnyObject[]!,inRegion region: CLBeaconRegion!) {
            NSLog("didRangeBeacons");
            var message:String = ""
            
            if(beacons.count > 0) {
                let nearestBeacon:CLBeacon = beacons[0] as CLBeacon
                
                switch nearestBeacon.proximity {
                case CLProximity.Far:
                    message = "You are far away from the beacon"
                case CLProximity.Near:
                    message = "You are near the beacon"
                case CLProximity.Immediate:
                    message = "You are in the immediate proximity of the beacon"
                case CLProximity.UnkNown:
                    return
                }
            } else {
                message = "No beacons are nearby"
            }
            
            NSLog("%@",message)
            sendlocalnotificationWithMessage(message)
    }
}

If you run this on iOS 8,you'll see a bunch of warnings in the Xcode log saying that your app hasn't requested permission to send notifications. This is a new iOS 8 requirement. Fortunately,it's pretty simple to do. We just need to add the following code to the application:didFinishLaunchingWithOptions: method. Anywhere should be fine,but I put it at the bottom,just before the return statement.

        if(application.respondsToSelector("registerUserNotificationSettings:")) {
            application.registerUserNotificationSettings(
                UIUserNotificationSettings(
                    forTypes: UIUserNotificationType.Alert | UIUserNotificationType.sound,categories: nil
                )
            )
        }

It checks to see if the UIApplication object responds to the registerUserNotificationSettings selector,so the app will still function as expected on iOS 7. However,if we're on iOS 8,it will request permission from the user to send notifications. Since this is just an example focusing on the iBeacon functionality,we're not handling the case where this is declined,but in a production app,this would be a good thing to do.

Now if you run the app,nothing will happen when it's foregrounded (we'll deal with that in a bit),but if you background it (press the home button) while in the presence of an iBeacon,you should see a steady stream of notifications letting you kNow your proximity to the beacon.

9. Clean Up

This will work as is,but let's tidy things up just a bit. Since we've implemented background ranging with background notifications,you'll get a lot of redundant alerts (one per second while the app is in the background),so we should modify things to only alert us when the range changes. First,we need to add a place to store the last proximity reading. Add the following property to the top of AppDelegate.swift,just below the declaration of the window and locationManager:

    var lastProximity: CLProximity?

Then,down in the didRangeBeacons method implementation,add this just before the switch statement that checks the proximity of the nearest beacon:

                if(nearestBeacon.proximity == lastProximity ||
                    nearestBeacon.proximity == CLProximity.UnkNown) {
                        return;
                }
                lastProximity = nearestBeacon.proximity;

If the proximity hasn't changed or is temporarily unkNown,the method returns and doesn't re-alert us.

That's great,but Now what happens if we leave the beacon range entirely? The device will keep trying to range beacons that are no longer in range which just wastes power. Luckily,the CLLocationManager will tell us via a different method when we have entered and exit the range,and we can start and stop the more detailed ranging operations accordingly. Add these methods to the CLLocationManagerDelegate extension to our App Delegate (just below the implementation of didRangeBeacons):

    func locationManager(manager: CLLocationManager!,didEnterRegion region: CLRegion!) {
            manager.startRangingBeaconsInRegion(region as CLBeaconRegion)
            manager.startUpdatingLocation()
            
            NSLog("You entered the region")
            sendlocalnotificationWithMessage("You entered the region")
    }
    
    func locationManager(manager: CLLocationManager!,didExitRegion region: CLRegion!) {
            manager.stopRangingBeaconsInRegion(region as CLBeaconRegion)
            manager.stopUpdatingLocation()
            
            NSLog("You exited the region")
            sendlocalnotificationWithMessage("You exited the region")
    }

This also logs and alerts us of the system-level region entry/exit.

10. Foreground display

(This part is greatly helped by screenshots,which we can't post yet because of the Apple NDA. In the meantime,you might find it helpful to refer back to ourObjective-C-based tutorialwhich has screenshots. The two are very similar here in terms of the Storyboard configuration.)

OK,things are great in background mode,but when the app is foregrounded,all we have is a plain white screen and no indication of what's happening. Let's fix that by adding a UITableView and populating it with information about all of the beacons in range.

Open the Main.storyboard file. Then select the main view to give it focus. Then,in the list in the bottom right (you may need to use the buttons in the top right corner of the screen to open the tray on the right side of the window),find a Table View (not a Table View Controller,since we're just using the existing view controller for Now to keep things simple). Drag it onto the view and position and scale it so that it takes up the entire view except the area taken up by the status bar at the top.

Now we need to declare a variable to hold a reference to this UITableView. We'll use the main view controller (ViewController.swift). At the top of the class declaration,inside the brackets but before any of the function declarations,add this:

    @IBOutlet var tableView: UITableView

Next,open the storyboard file again. Then option-click (or right-click) on the table view you just added. In the context menu that pops up,drag from the little circle to the right of dataSource over to the View Controller entry in the left portion of the storyboard view.

Do the same for delegate and New Referencing Outlet. When you drop the connection for New Referencing Outlet,you'll get a pop-up asking which variable the table view should map to. Select tableView,which matches the name of the property we just created.

Now we need to declare our View Controller to implement the protocols required by the above connections,UITableViewDataSource and UITableViewDelegate. Add them to the declaration of your view controller class near the top of ViewController.swift,like this:

class ViewController: UIViewController,UITableViewDataSource,UITableViewDelegate {

Now declare an array of CLBeacons at the top of the ViewController class declaration (you'll also need to import CoreLocation into ViewController.swift to do this):

    var beacons: CLBeacon[]

When the beacons are ranged in the app delegate,Now we need to pass the array of beacons to the View Controller and tell the table view to update itself. Add the following code to the top of locationManager:didRangeBeacons:inRegion in the App Delegate CLLocationManagerDelegate extension:

            let viewController:ViewController = window!.rootViewController as ViewController
            viewController.beacons = beacons as CLBeacon[]?
            viewController.tableView.reloadData()

Whenever beacons are ranged,they are passed to the view controller,and the tableView is reloaded with the new data.

Now we just need to implement -tableView:numberOfRowsInSection: and -tableView:cellForRowAtIndexPath: in our View Controller. These methods are called by the table view so it can update itself with the latest data. As with the CLLocationManagerDelegate methods,we'll implement these in class extensions:

extension ViewController: UITableViewDataSource {
    func tableView(tableView: UITableView!,numberOfRowsInSection section: Int) -> Int {
            if(beacons != nil) {
                return beacons!.count
            } else {
                return 0
            }
    }
    
    func tableView(tableView: UITableView!,cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
            var cell:UITableViewCell? = 
                tableView.dequeueReusableCellWithIdentifier("MyIdentifier") as? UITableViewCell
            
            if(cell == nil) {
                cell = UITableViewCell(style: UITableViewCellStyle.Subtitle,reuseIdentifier: "MyIdentifier")
                cell!.selectionStyle = UITableViewCellSelectionStyle.None
            }
            
            let beacon:CLBeacon = beacons![indexPath.row]
            var proximityLabel:String! = ""
            
            switch beacon.proximity {
            case CLProximity.Far:
                proximityLabel = "Far"
            case CLProximity.Near:
                proximityLabel = "Near"
            case CLProximity.Immediate:
                proximityLabel = "Immediate"
            case CLProximity.UnkNown:
                proximityLabel = "UnkNown"
            }
            
            cell!.textLabel.text = proximityLabel
            
            let detailLabel:String = "Major: \(beacon.major.integerValue)," +
                "Minor: \(beacon.minor.integerValue)," +
                "RSSI: \(beacon.RSSi as Int)," +
                "UUID: \(beacon.proximityUUID.UUIDString)"
            cell!.detailTextLabel.text = detailLabel
            
            return cell
    }
}

extension ViewController: UITableViewDelegate {
    
}

Since we're not doing any cell selection or other functionality that would require delegate callbacks,our UITableViewDelegate extension is empty for Now,but that's where you'd start implementing that functionality when you're ready.

Conclusion

Now we've built a iBeacon app using Swift that can range beacons in the foreground and background and display the data and push alerts,so we're going to stop there for Now. You can also download theentire project from GitHubif you'd rather not build it up piece by piece. I hope this helps you get up and running and hopefully understand a bit more about iBeacon and how it's used with iOS 7/8. If you have questions or Feedback on this tutorial,leave us a comment!

Swift based iBeacon App Development with CoreLocation on Apple iOS 7/8的更多相关文章

  1. ios – 在区域监控时检测iBeacon需要多长时间?

    采取这种情况:用户在口袋里有一个通过iBeacon的iPhone.她的手机是区域监控.应用程序被唤醒时,现实世界需要多少时间才能进入该地区?

  2. ios – iBeacon:didEnterRegion和didDetermineState(CLRegionStateInside)之间有什么区别?

    当用户进入某个地区时,我想发布通知.但是,由于同样的两个CLLocationManagerDelegate方法,我很困惑.如何正确使用这两种方法?有些人说如果应用程序在该区域启动,则需要“didDetermineState”方法来启动区域观察.谢谢,解决方法苹果的documentationforCLLocationManager状态:Thelocationmanagercallsthismetho

  3. ios – 我可以只从一个蓝牙广播多个ibeacon信号吗?如何

    我想用ipad的蓝牙模拟多个ibeacon信号,是否可能解决方法您不能同时进行多个传输,但您可以通过使用计时器在两个或更多个发送器之间切换来模拟这种情况.当作为iBeacon进行传输时,iOS设备通常每秒发送10个广告包.但接收者只希望在正常操作中每秒至少接收一次数据包.尝试设置一个定时器在两个iBeacon发射器之间来回切换(关闭一个然后打开另一个).像这样:我测试了这个并且它可以工作–第二个i

  4. iBeaconswift

    随着这一技术的发展,苹果在2013年WWDC大会上,苹果推出iBeacon技术。该技术允许开发人员开发能够使用iBeacon硬件传感器的iOS应用程序,来为相应的应用程序提供更加精准的位置信息。2014年WWDC大会上,苹果表示,对iBeacon技术进行了改善,借助该技术,应用程序现在能够跟踪到用户所在的楼层的精确位置信息。iBeacon的工作方式是Transmitter-Receiver,即基站-接收机模式的。这里列举个iBeacon的使用场景:在房屋中介中使用。

  5. Swift based iBeacon App Development with CoreLocation on Apple iOS 7/8

    We'vehadanumberofcustomerswhowanttouseApple'snewprogramminglanguageSwifttodevelopiBeaconapplications,sowedecidedtodevelopatutorialtomakeiteasiertogetupandrunning.RightNow,Swift,Xcode6,andiOS8areallcov

  6. iBeacon 的第一篇基于Swift实现

    随着这一技术的发展,苹果在2013年WWDC大会上,苹果推出iBeacon技术。2014年WWDC大会上,苹果表示,对iBeacon技术进行了改善,借助该技术,应用程序现在能够跟踪到用户所在的楼层的精确位置信息。iBeacon的工作方式是Transmitter-Receiver,即基站-接收机模式的。这里列举个iBeacon的使用场景:在房屋中介中使用。甚至于还有一个老外用iBeacon做了一个实景的经营游戏,点击这里观看。

  7. ibeacon – 用于Beacon检测的Swift2.3代码

    我们正处于开发Swift2.2应用程序的高级阶段,因此决定在此期间迁移到2.3并稍后进行完整的Swift3迁移.但是我们无法在转换到Swift2.3后获得信标检测工作.方法“didRangeBeacons”不断返回一个空数组.相同的代码在Swift2.2中工作,因此我们知道我们拥有所有权限等.此外,如果我们在同一个ipad上打开“定位”应用程序,那么我们的应用程序也会开始在“didRangeBeacons”中返回数据.尝试了各种版本的应用程序,所有Swift2.3应用程序的行为方式都相同.无法弄清楚Loc

  8. 如何在IOS中使用IBeacon

    这篇文章主要介绍了如何在IOS中使用IBeacon,想了解IBeacon的同学,一定要看一下

  9. ios7 – 是否可以使用ibeacon API访问所有信标?

    我即将完成使用具有UUID的Estimote信标的应用程序在我的项目中硬编码,列出了使用ibeaconAPI的所有Estimote信标,但是当我试图使用设备UUID将我自己的设备作为信标发射器时,这与estimoteUUID不同,我无法找到它,因为我在代码中提到的UUID是Estimote的.所以我的问题是,有什么方法可以找到我可以用苹果的ibeaconAPI跟踪的所有信标?

  10. ios – 如何将数据发送到变成iBeacon的iphone?

    如何将数据发送到充当iBeacon的iPhone?我正在寻找以下过程:>搜索附近的iBeacons>连接到一些iBeacon>在设备之间交换数据有谁知道如何把不同的蓝牙功能放在一起这可能吗?

随机推荐

  1. Swift UITextField,UITextView,UISegmentedControl,UISwitch

    下面我们通过一个demo来简单的实现下这些控件的功能.首先,我们拖将这几个控件拖到storyboard,并关联上相应的属性和动作.如图:关联上属性和动作后,看看实现的代码:

  2. swift UISlider,UIStepper

    我们用两个label来显示slider和stepper的值.再用张图片来显示改变stepper值的效果.首先,这三个控件需要全局变量声明如下然后,我们对所有的控件做个简单的布局:最后,当slider的值改变时,我们用一个label来显示值的变化,同样,用另一个label来显示stepper值的变化,并改变图片的大小:实现效果如下:

  3. preferredFontForTextStyle字体设置之更改

    即:

  4. Swift没有异常处理,遇到功能性错误怎么办?

    本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请发送邮件至dio@foxmail.com举报,一经查实,本站将立刻删除。

  5. 字典实战和UIKit初探

    ios中数组和字典的应用Applicationschedule类别子项类别名称优先级数据包contactsentertainment接触UIKit学习用Swift调用CocoaTouchimportUIKitletcolors=[]varbackView=UIView(frame:CGRectMake(0.0,0.0,320.0,CGFloat(colors.count*50)))backView

  6. swift语言IOS8开发战记21 Core Data2

    上一话中我们简单地介绍了一些coredata的基本知识,这一话我们通过编程来实现coredata的使用。还记得我们在coredata中定义的那个Model么,上面这段代码会加载这个Model。定义完方法之后,我们对coredata的准备都已经完成了。最后强调一点,coredata并不是数据库,它只是一个框架,协助我们进行数据库操作,它并不关心我们把数据存到哪里。

  7. swift语言IOS8开发战记22 Core Data3

    上一话我们定义了与coredata有关的变量和方法,做足了准备工作,这一话我们来试试能不能成功。首先打开上一话中生成的Info类,在其中引用头文件的地方添加一个@objc,不然后面会报错,我也不知道为什么。

  8. swift实战小程序1天气预报

    在有一定swift基础的情况下,让我们来做一些小程序练练手,今天来试试做一个简单地天气预报。然后在btnpressed方法中依旧增加loadWeather方法.在loadWeather方法中加上信息的显示语句:运行一下看看效果,如图:虽然显示出来了,但是我们的text是可编辑状态的,在storyboard中勾选Editable,再次运行:大功告成,而且现在每次单击按钮,就会重新请求天气情况,大家也来试试吧。

  9. 【iOS学习01】swift ? and !  的学习

    如果不初始化就会报错。

  10. swift语言IOS8开发战记23 Core Data4

    接着我们需要把我们的Rest类变成一个被coredata管理的类,点开Rest类,作如下修改:关键字@NSManaged的作用是与实体中对应的属性通信,BinaryData对应的类型是NSData,CoreData没有布尔属性,只能用0和1来区分。进行如下操作,输入类名:建立好之后因为我们之前写的代码有些地方并不适用于coredata,所以编译器会报错,现在来一一解决。

返回
顶部