├── DETAIL.md
├── README.md
├── client-iphone
├── .DS_Store
├── piBeacon-iphone.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcuserdata
│ │ │ └── matt.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ └── xcuserdata
│ │ └── matt.xcuserdatad
│ │ └── xcschemes
│ │ ├── piBeacon-iphone.xcscheme
│ │ └── xcschememanagement.plist
├── piBeacon-iphone
│ ├── AppDelegate.h
│ ├── AppDelegate.m
│ ├── Base.lproj
│ │ └── Main.storyboard
│ ├── FirstViewController.h
│ ├── FirstViewController.m
│ ├── Images.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ ├── LaunchImage.launchimage
│ │ │ └── Contents.json
│ │ ├── first.imageset
│ │ │ ├── Contents.json
│ │ │ ├── first.png
│ │ │ └── first@2x.png
│ │ ├── second.imageset
│ │ │ ├── Contents.json
│ │ │ ├── second.png
│ │ │ └── second@2x.png
│ │ └── unknown-user.imageset
│ │ │ ├── Contents.json
│ │ │ └── unknown-user.png
│ ├── SecondViewController.h
│ ├── SecondViewController.m
│ ├── en.lproj
│ │ └── InfoPlist.strings
│ ├── main.m
│ ├── piBeacon-iphone-Info.plist
│ ├── piBeacon-iphone-Prefix.pch
│ └── piBeacon
│ │ ├── ModelEngagement.h
│ │ ├── ModelEngagement.m
│ │ ├── piBeacon.h
│ │ ├── piBeacon.m
│ │ ├── piBeaconDetailViewController.h
│ │ ├── piBeaconDetailViewController.m
│ │ ├── piBeaconDetailViewController.xib
│ │ ├── piBeaconProximityAlertViewController.h
│ │ ├── piBeaconProximityAlertViewController.m
│ │ ├── piBeaconProximityAlertViewController.xib
│ │ ├── piBeaconUserDetailViewController.h
│ │ ├── piBeaconUserDetailViewController.m
│ │ └── piBeaconUserDetailViewController.xib
└── piBeacon-iphoneTests
│ ├── en.lproj
│ └── InfoPlist.strings
│ ├── piBeacon-iphoneTests-Info.plist
│ └── piBeacon_iphoneTests.m
├── ibeacon-node-collector
├── app.js
├── app.json
├── boot
│ └── init.js
├── datasources.json
├── models.json
└── package.json
└── screenshots
├── api-ibeacons.png
├── ble-analytics.png
├── ble-apps-2.png
├── ble-apps.png
├── ble-mobile-multi.png
├── ble-mobile.png
├── ble-ranging.png
├── console-run.png
├── estimote-ibeacon.png
├── explorer-ibeacons.png
├── image1.png
├── image2.png
├── loopback-explorer-beacon.png
├── loopback-explorer.png
└── loopback-filter-near.png
/DETAIL.md:
--------------------------------------------------------------------------------
1 |
2 | UNSTABLE - WORK IN PROGRESS
3 |
4 |
5 | Tracking mobile iBeacons and BlueTooth Low Energy engagements with Node.js
6 | --
7 |
8 | ###iBeacons are Apples convention for handling Bluetooth Low Energy engagements
9 |
10 | iBeacons are Bluetooth Low Energy(BLE) wireless sensors that support a specific [HID profile schema ](https://developer.bluetooth.org/TechnologyOverview/Pages/HID.aspx) instead of the traditional [GATT profile ](http://en.wikipedia.org/wiki/Bluetooth_profile#Attribute_Profile_.28ATT.29). Additionally Apple iBeacons provide convention, libraries and integration into mobile location services. iBeacons breaks down BLE into 3 core features: broadcast, monitoring and ranging.
11 |
12 | Bluetooth Low Energy Energy Beacons have come into the world around us. Apple's integration of Bluetooth technology into branded iBeacons will inevitable proliferate the technology. Large implementations of the technology such as [ MLB's installation into ball parks ](http://techcrunch.com/2013/09/29/mlbs-ibeacon-experiment-may-signal-a-whole-new-ball-game-for-location-tracking/), and [PayPal's Beacon ](https://www.paypal.com/us/webapps/mpp/beacon ) payment system are making facilities and locations smart. Startups like [estimote](http://estimote.com) , [Brick Trends](http://bricktrends.com), [Pebble](http://pebble.com) are making it easier for developers and businesses to integrate the technology into their customers daily lives. All this is making your mobile device 'the new endpoint' and mobile application's more of a digital proxy for users interacting in real world.
13 |
14 | ###GPS gives devices 'vicinity' awareness, BLE iBeacons gives devices 'proximity' awareness
15 |
16 | Leveraging Bluetooth your mobile device can tell how far away your user is from a bluetooth 'beacon'. GPS gave mobile devices the power of vicinity; your device knows where it is with a neighborhood block accuracy (provided you had line of sight to a GPS satellite). This singular technology gave way to location targeted push notifications with geo fencing, time and location relevant mobile Ad's, geo caching games and of course everyone's favorite "Dude Where's my Car" mobile apps.
17 |
18 | BlueTooth LE and iBeacons will extend these use cases by illuminate the regions of our lives in the shadow of GPS line of Sight. In-store retail "brick" analytics (currently brick and mortar retailers have no idea where you are in their store or how your spending your time ) is likely to see the largest shift.
19 |
20 | Retail kiosks, end-caps, and payment terminals are blind, dumb and mute to your mobile device. Effectively **the urinal in the men's bathroom is smarter than your average retail kiosk; at least the urinal knew to flush when you stepped away**. iBeacons will make facilities, displays and the devices that power them aware of the mobile device ( and user ) in front of them.
21 |
22 | ### Location Aware devices are going to change Retail
23 |
24 | With [70 percent of smartphone shoppers use a store locator to plan their shopping trip](http://www.nielsen.com/us/en/newswire/2013/a-mobile-shoppers-journey--from-the-couch-to-the-store--and-back.html). Mobile apps will play an integral roll in store shopping experience.
25 |
26 | Retail and real world 'brick and mortar' vendors know the power of Mobile applications, justified by stats such as [Forty-six percent of shoppers say they are less likely to comparison shop when using a mobile app](http://www.comscore.com/Insights/Presentations_and_Whitepapers/2013/Choices_Channels_and_Convenience_Enhancing_the_Online_Shopping_Experience)
27 |
28 | Coupling purchases and the fact that [25 million Americans use Coupon apps each month](https://www.npd.com/wps/portal/npd/us/news/press-releases/pr_120523/) and the [prediction that the number of U.S. adult smartphone users who also use mobile coupons will jump to 40.8 million at the end of 2013](http://www.emarketer.com/Article/Digital-Coupons-Mobile-Give-Cheapskates-Staying-Power/1009847#Jy3uKPRgRE7lZiuJ.99) gives ecosystem opportunity around BLE and iBeacon technology.
29 |
30 | Bluetooth enabled accessories are projected to experience massive growth—220 million units this year to nearly 1 billion per year by 2016 (ABI Research)
31 |
32 | ###Why does Node Matter
33 | Bluetooth engagements can create analytic 'engagement' 100 packages every millisecond, and bursting this information to another mobile devices; possibly in the hands of retail associate. This information needs to be in the hands ( or devices ) of people that can engage with the potential customer in realtime. Pairing in store realtime analytics with shopper loyalty programs gives retail floor associates opportunity to engage at the moment of interest. Node apps can collect this information and trigger Push Notifications, email alerts and realtime at the time of opportunity.
34 |
35 | Additionally dashboards can give daily and realtime analytics to floor managers on which associates are effectively engaging with their customers.
36 |
37 | Node.js realtime low latency response and request architecture makes it a perfect collector, and aggregator for this information. Node can be deployed on the cloud or even in the facility on a device that is collecting this information.
38 |
39 | Combined with the variety of NPM modules available for displaying this data, delivering it cloud or storing it in databases or 3rd party analytics engines makes Node.js the perfect technology for the middle tier. Weather you are running the bluetooth sniffing Node application on site in a Raspberry Pi, a Laptop or as a cloud aggregator Node fits the need perfectly.
40 |
41 | ### How intro :
42 |
43 | All Bluetooth Low Energy devices (including iBeacons) are identified via a UUID (Device Identifier). Devices either operate as Central or a Peripheral configuration. The Mobile Application 'Herald' that goes along with this posting can operate as both a Central (connecting and interacting with Peripheral's in its proximity) and also as Peripheral allowing other Central's to discover and interact with it.
44 |
45 | The users iPhone and Android device acts as an moving blueTooth 'endpoint' in which the dynamic BLE 'network' discovers and connects to the application. Once the 'Herald' app on the users device connects and interacts with the beacon devices in the word; Herald will report back the interaction ( referred to as an engagement in this sample ) to the server.
46 |
47 | Since we want to share and report these interactions platform then your going to need to store the data on the Server. So I built a small node.js mobile servlet that catches the BLE Beacon engagement and stores the information for later analysis and review.
48 |
49 | If you want to test it out the mobile application is preconfigured to use a staged instance of the server; of course you can also stand up your own supporting server by deploying the LoopBack Node.js Server on your Cloud Provider of choice or on your own machine.
50 |
51 | ### How mobile client : iBeacon iPhone Application
52 |
53 | The [iBeacon iPhone Application](/client-iphone) is a simple native iOS application that allows configuration as a Central, a Peripheral or both. Once you download the github repo you can run the application from XCode in the simulator ( you will not be able to activate the BlueTooth features unless you have a secondary blueTooth device attached to your dev machine), or install on an iOS device connected to your host machine.
54 |
55 | The initial splash screen will give you an idea where the app name came from. The Second tab is where the magic happens. you can enable your iPhone to to 'Advertise', making your phone look like a Peripheral to other Central devices in the vicinity. Additionally you can enable 'BLE ranging' and your device will look for other iBeacons and report back the 'range' or proximity of the BLE Peripheral. The TextField below each of the switches shows the identification the device is advertising and ranging as.
56 |
57 | #### iPhone iBeacon Demo App
58 |
59 |
60 |
61 |
62 | You can find the source code on [github](http://github.com/mschmulen/tracking-bluetooth-ibeacons-with-node) and experiment with iBeacons and BLE devices yourself.
63 |
64 | 1. Start from simple Tab application
65 |
66 | 2. Add the iOS frameworkS
67 | CoreBluetooth.framework
68 | CoreLocation.framework
69 |
70 | ##### Generating your unique proximityUUID
71 |
72 | To genette a unique proximityUUID open the terminal and run the ```uuidgen``` tool.
73 |
74 | ```
75 | AF23CFD3-1F95-42B8-8F2C-FEAC039D6F92
76 | ```
77 |
78 | you can update the harald application with your unique proximityUUID by modifying the kUUID string in iBeaconViewController.m
79 |
80 | ```
81 | static NSString * const kUUID = @"AF23CFD3-1F95-42B8-8F2C-FEAC039D6F92";
82 | ```
83 |
84 | major and minor
85 |
86 | ### Track you mobile BlueTooth engagements with a node.js servlet :
87 |
88 | TBD
89 |
90 | ### How hardware
91 |
92 | If you have 2 iOS7 devices then you can explore the interaction. Additionally if you have a BlueTooth embedded device such as the
93 | [Ti cc2540 & cc2541 sensor tag](http://www.ti.com/ww/en/wireless_connectivity/sensortag/index.shtml?DCMP=sensortag&HQS=sensortag-bn) then you can explore the use case as it would be for most real world use cases. Check out the [Ti SensorTag User Guide](http://processors.wiki.ti.com/index.php/SensorTag_User_Guide) for more information on the Ti sensor tag and kit.
94 |
95 | ** a quick note on debugging, ios7 will not allow you to debug via the simulator, so you will have debug through a connected iOS device **
96 |
97 | Also check out some of these BLE device vendors that provide hardware beacon devices:
98 |
99 | - [redbearlab] (http://redbearlab.com/ibeacon/)
100 | - [kontakt.io](http://kontakt.io/)
101 |
102 | ### References
103 |
104 | ---
105 |
106 | Developer resources and reference documents
107 |
108 | - [corebluetooth-doesnt-let-you-see-ibeacons](http://developer.radiusnetworks.com/2013/10/21/corebluetooth-doesnt-let-you-see-ibeacons.html)
109 | - [Lost-and-Found Bluetooth Accessory 'Tile' Passes $1 Million in Pre-Orders](http://www.macrumors.com/2013/07/15/lost-and-found-bluetooth-accessory-tile-passes-1-million-in-pre-orders/)
110 | - [Android iBeacon Library](http://developer.radiusnetworks.com/ibeacon/android/)
111 | - [Bluetooth devices to gain notification support in iOS 7 & Mavericks with Apple's new APIs](http://appleinsider.com/articles/13/06/13/bluetooth-devices-to-gain-notification-support-in-ios-7-mavericks-with-apples-new-apis)
112 | - [With iBeacon, Apple is going to dump on NFC and embrace the internet of things](http://gigaom.com/2013/09/10/with-ibeacon-apple-is-going-to-dump-on-nfc-and-embrace-the-internet-of-things/)
113 | - [github.com/manishnath/iBeaconCenter](https://github.com/manishnath/iBeaconCenter)
114 | - [How to Make an iBeacon Out of a Raspberry Pi](http://developer.radiusnetworks.com/2013/10/09/how-to-make-an-ibeacon-out-of-a-raspberry-pi.html)
115 | - [http://stackoverflow.com/questions/16151360/use-bluez-stack-as-a-peripheral-advertiser/19039963#19039963](http://stackoverflow.com/questions/16151360/use-bluez-stack-as-a-peripheral-advertiser/19039963#19039963)
116 | - [whats-new-in-bluetooth-le-ios-7](http://www.doubleencore.com/2013/09/whats-new-in-bluetooth-le-ios-7/)
117 | - [few-ios-7-tidbits-you-probably-didn-t-hear-about](http://blog.greggant.com/post/62060213476/a-few-ios-7-tidbits-you-probably-didn-t-hear-about)
118 | - [developer.apple.com/AboutCoreBluetooth/Introduction.html](https://developer.apple.com/library/ios/documentation/NetworkingInternetWeb/Conceptual/CoreBluetooth_concepts/AboutCoreBluetooth/Introduction.html#//apple_ref/doc/uid/TP40013257-CH1-SW1)
119 | - [Getting started with Xcode 4.x and Bluetooth Smart (BLE) on iOS](http://web.stalliance.no/blelogg/?page_id=52)
120 | - [BLE Tutorial 2](http://web.stalliance.no/blelogg/?page_id=180)
121 | - [A look at the CBCentralManager class of iOS](http://web.stalliance.no/blelogg/?page_id=131)
122 | - [iBeacons !](http://web.stalliance.no/blelogg/?p=269)
123 | - [Ti Bluetooth SensorTag ](http://processors.wiki.ti.com/index.php/Bluetooth_SensorTag?DCMP=lprf-stdroid&HQS=lprf-stdroid-pr-wiki1)
124 |
125 |
126 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Tracking mobile BlueTooth LE iBeacon engagements with Node.js
2 | --
3 |
4 | ###iBeacons and Bluetooth Low Energy (BLE)
5 | Bluetooth Low Energy (BLE) beacons have come into the world around us with Apple’s branded iBeacon which gives branded convention and integration of the BLE devices. iBeacons break down BLE into 3 core features: broadcast, monitoring and ranging.
6 |
7 |
8 |
9 | iBeacon is similar in some ways to mobile GPS Geolocation services. Unlike GPS Geolocation, which gives mobile apps vicinity awareness (limited to outdoor scenarios that have line of sight to GPS satellites), BLE iBeacon gives mobile application’s proximity awareness from other iBeacon devices. The distance can be used to triangulate where the user is from a known fixed beacon location or identify if the user is within a predefined nominal “immediate”, “near” or “far” proximity to a device.
10 |
11 |
12 |
13 | ###Bluetooth proliferation
14 | The branding and assimilation of BLE into Apples iOS7 platform is causing a proliferation of Bluetooth ‘beacon-ing’ technology. Large implementations of the technology such as [ MLB's installation into ball parks ](http://techcrunch.com/2013/09/29/mlbs-ibeacon-experiment-may-signal-a-whole-new-ball-game-for-location-tracking/), and [PayPal's Beacon ](https://www.paypal.com/us/webapps/mpp/beacon ) payment system are making facilities and locations smart. Startups like [Estimote](http://), [Shelf Bucks](http://shelfbucks.com/), [Pebble](http://pebble.com) are making it easier for developers and businesses to integrate the technology into their customers’ daily lives and their mobile app’s. The technology is poised to forever change kiosks, retail end-caps, payment terminals and the facilities around us. Historically these engagement touch points were blind, dumb and mute to your mobile device. Historically *the restrooms in the bathroom were the smartest machine in your average retail facility; at least the toilet knew to flush when a person stepped away*. iBeacons will make stores, and the devices inside them aware of the mobile devices (more importantly user) in the facility. This gives analytics and insight into the previously dark world of “in store” behavior and engagement [changing everything in retail](http://www.forbes.com/sites/centurylink/2013/10/31/how-apples-ibeacon-will-change-everything-for-retail-analytics/) shopping experiences.
15 |
16 | ###You are your mobile ‘signature'
17 | When you open a BLE enabled mobile app your Blue Tooth ‘signature' tracks your location and behavior by your proximity to other BLE aware machines and devices. In a similar way to how a web cookie allows retailers to track your journey through a web site, your real world engagements can be tracked as you interact with BLE aware devices.
18 |
19 | ###The Power of Node.js
20 | Using StrongLoops [LoopBack](http://strongloop.com/mobile-application-development/loopback/) and the open source [bleacon npm](https://npmjs.org/package/bleacon) package it’s very easy to track an iBeacon enabled mobile app using Node.js. Will show you how to do this on your local machine and track the engagements from the machine interaction for later analysis and reporting.
21 |
22 | ###Tracking BLE engagements with 6 commands and 25 LOC
23 | You can build the demo on your own and see it run on a mac book pro (requires Mavericks) with Node.js by simply cloning the repo ‘git clone https://github.com/mschmulen/tracking-bluetooth-ibeacons-with-node’ and running it with ‘slc run app.js’
24 | or build it from scratch by following the instructions below:
25 |
26 | **Commands:**
27 |
28 | ```
29 | npm install -g strong-cli
30 | slc lb project ibeacon-node-collector
31 | cd ibeacon-node-collector
32 | npm install --save bleacon
33 | slc lb model ibeacon
34 | slc lb model engagement
35 | ```
36 |
37 | The commands above installs the [strong-cli](http://https://npmjs.org/package/strong-cli)making giving us access to the ```slc lb``` commands to quickly scaffold an API tier and add our ```beacon``` and ```engagement``` data models. Installs the [bleacon](https://npmjs.org/package/bleacon) npm package and dependencies.
38 |
39 | **Code:**
40 |
41 |
42 | Create a folder /boot under the ibeacon-node-collector folder and a file init.js . Add the 10 lines of code below to the newly created ~/ibeacon-node-collector/boot/init.js file.
43 |
44 | ```
45 | var ibeacon = app.models.ibeacon;
46 | var Bleacon = require('bleacon');
47 | var ibeaconCache = new Array();
48 |
49 | Bleacon.on('discover', function(bleacon) {
50 | console.log( bleacon );
51 |
52 | var myID = 0;
53 | var guid = bleacon.uuid + bleacon.major + bleacon.minor;
54 | console.log ( guid + ":" + bleacon.uuid + "," + bleacon.major + "," + bleacon.minor );
55 |
56 | if ( guid in ibeaconCache ) { myID = ibeaconCache[guid]; }
57 |
58 | ibeacon.upsert(
59 | { id: myID , guid:guid, uuid:bleacon.uuid, major:bleacon.major, minor:bleacon.minor},
60 | function( error, _ibeacon)
61 | {
62 | ibeaconCache[guid] = _ibeacon.id;
63 | if ( error ) { console.log( "error on upsert " ); }
64 | else {
65 | console.log( "upsert - :" + _ibeacon.id + " guid " + _ibeacon.guid );
66 | var eng = app.models.engagement;
67 | eng.create({ pBeaconID: _ibeacon.id, timestamp: Date.now(), rssi: bleacon.rssi, proximity: bleacon.proximity });
68 | } //end else success
69 | }); //end upser
70 |
71 | var signal = [bleacon.rssi/5];
72 | var xs = new Array(Math.floor(-bleacon.rssi/2) + 1).join('x');
73 | console.log("rssi:" +xs);
74 |
75 | });//end on discover
76 |
77 | Bleacon.startScanning();
78 | ```
79 |
80 | Test the implementation by installing an app that has iBeacon support. I'm using the [Estimote Virtual Beacon on the App Store](https://itunes.apple.com/us/app/estimote-virtual-beacon/id686915066?mt=8) for this demo.
81 |
82 | Start the Estimote App in 'iBeacon broadcasting' mode.
83 |
84 |
85 |
86 | Run the node application on your host machine with
87 |
88 | ```slc run app.js```
89 |
90 | In addition to entering the engagement in the in memory data store the code above will shows the BLE [ Received signal strength indication (RSSI) ](http://en.wikipedia.org/wiki/Received_signal_strength_indication) to the console log as your Node application receives Bleacon discover events. The RSSI value is used to determine the proximity (distance) of a BLE peripheral.
91 |
92 |
93 |
94 | ###Run your node app anywhere and persist the data to MongoDB
95 |
96 | Since the app is using Node can run the collector anywhere that supports the Node.js runtime, such as on a Raspberry-Pi. Allowing you to to create a simple “sniffer” device that when plugged into the wall will track all the Bluetooth engagements that occur in your home, office or store.
97 |
98 | If you want to persist your analytics data you can simply change the LoopBack model binding in ```datasources.json``` to point to supported data store such as MongoDB, MySQL, or Oracle. you can find more information on configuring your Node.js API to work with LoopBack supported data stores and connectors [in the StrongLoop documentation](http://docs.strongloop.com/display/DOC/Data+sources+and+connectors).
99 |
100 | Lets look at some of the beacon signatures and engagements that we have captured using the LoopBack Explorer feature on our local machine by opening [http://localhost:3000/explorer/](http://localhost:3000/explorer/) in our web browser.
101 |
102 |
103 |
104 | ###Search and filter API for engagement analysis
105 |
106 | Using the LoopBack API you can get all the beacon signatures in the system from JSON API endpoint at [http://localhost:3000/api/engagements](http://localhost:3000/api/engagements).
107 |
108 |
109 |
110 | We can also filter engagements based on a GUID using the built in
111 | [filter functionality] (http://localhost:3000/api/engagements?filter[where][cBeaconGUID]=87209302c7f24d56b1d114eadd0ce41f15) with the following url request ```http://localhost:3000/api/engagements?filter[where][id]=1``` .
112 |
113 | We can also do complex filtering against engagement [time] (http://localhost:3000/api/engagements?filter[where][id]=87209302c7f24d56b1d114eadd0ce41f15&filter[where][time][gt]=87209302c7f24d56b1d114eadd0ce41f16), [proximity] (http://localhost:3000/api/engagements?filter[where][proximity]=near ) or any mix of the available parameters.
114 |
115 | ``` http://localhost:3000/api/engagements?filter[where][id]=2&filter[where][proximity]=near ```
116 |
117 |
118 |
119 | ###Identify anonymous mobile beacon signatures and track people
120 |
121 | Match the user to the anonymous signature and start tracking people within 100 feet of our machine.
122 |
123 | If you want to go the extra mile, simply use the built in LoopBack ```user model``` object by adding an index reference to the ```beacon model```. When you convert all the anonymous beacon signatures to known users the engagements analytics show real world user behavior.
124 |
125 | The conversion from an anonymous unknown user BLE iBeacon signature to known user behavior is the reason that retailers want you to open their customer loyalty app in the store and login. Binding your user profiler to the device and allowing them to track your in store loitering and behavior (and possibly target engagements at you) in the same way they track your shopping behaviors online.
126 |
--------------------------------------------------------------------------------
/client-iphone/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mschmulen/tracking-bluetooth-ibeacons-with-node/2798b01ac4af5ff7ad8a46019ea8ea1b8178d6a2/client-iphone/.DS_Store
--------------------------------------------------------------------------------
/client-iphone/piBeacon-iphone.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | AEB0E7B1186A7A83005475E0 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AEB0E7B0186A7A83005475E0 /* Foundation.framework */; };
11 | AEB0E7B3186A7A83005475E0 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AEB0E7B2186A7A83005475E0 /* CoreGraphics.framework */; };
12 | AEB0E7B5186A7A83005475E0 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AEB0E7B4186A7A83005475E0 /* UIKit.framework */; };
13 | AEB0E7BB186A7A83005475E0 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = AEB0E7B9186A7A83005475E0 /* InfoPlist.strings */; };
14 | AEB0E7BD186A7A83005475E0 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = AEB0E7BC186A7A83005475E0 /* main.m */; };
15 | AEB0E7C1186A7A83005475E0 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = AEB0E7C0186A7A83005475E0 /* AppDelegate.m */; };
16 | AEB0E7C4186A7A83005475E0 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = AEB0E7C2186A7A83005475E0 /* Main.storyboard */; };
17 | AEB0E7C7186A7A83005475E0 /* FirstViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = AEB0E7C6186A7A83005475E0 /* FirstViewController.m */; };
18 | AEB0E7CA186A7A83005475E0 /* SecondViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = AEB0E7C9186A7A83005475E0 /* SecondViewController.m */; };
19 | AEB0E7CC186A7A83005475E0 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = AEB0E7CB186A7A83005475E0 /* Images.xcassets */; };
20 | AEB0E7D3186A7A83005475E0 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AEB0E7D2186A7A83005475E0 /* XCTest.framework */; };
21 | AEB0E7D4186A7A83005475E0 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AEB0E7B0186A7A83005475E0 /* Foundation.framework */; };
22 | AEB0E7D5186A7A83005475E0 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AEB0E7B4186A7A83005475E0 /* UIKit.framework */; };
23 | AEB0E7DD186A7A83005475E0 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = AEB0E7DB186A7A83005475E0 /* InfoPlist.strings */; };
24 | AEB0E7DF186A7A83005475E0 /* piBeacon_iphoneTests.m in Sources */ = {isa = PBXBuildFile; fileRef = AEB0E7DE186A7A83005475E0 /* piBeacon_iphoneTests.m */; };
25 | AEB0E7E9186A7B82005475E0 /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AEB0E7E8186A7B82005475E0 /* CoreBluetooth.framework */; };
26 | AEB0E7EB186A7B89005475E0 /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AEB0E7EA186A7B89005475E0 /* CoreLocation.framework */; };
27 | AEB0E7EF186C9324005475E0 /* ModelEngagement.m in Sources */ = {isa = PBXBuildFile; fileRef = AEB0E7EE186C9324005475E0 /* ModelEngagement.m */; };
28 | AEB0E7F2186C94B3005475E0 /* piBeacon.m in Sources */ = {isa = PBXBuildFile; fileRef = AEB0E7F1186C94B3005475E0 /* piBeacon.m */; };
29 | AEB0E7F9186CD9E8005475E0 /* piBeaconDetailViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = AEB0E7F7186CD9E8005475E0 /* piBeaconDetailViewController.m */; };
30 | AEB0E7FA186CD9E8005475E0 /* piBeaconDetailViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = AEB0E7F8186CD9E8005475E0 /* piBeaconDetailViewController.xib */; };
31 | AEB0E7FE186CDAE9005475E0 /* piBeaconUserDetailViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = AEB0E7FC186CDAE9005475E0 /* piBeaconUserDetailViewController.m */; };
32 | AEB0E7FF186CDAE9005475E0 /* piBeaconUserDetailViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = AEB0E7FD186CDAE9005475E0 /* piBeaconUserDetailViewController.xib */; };
33 | AEB0E8031870B8FE005475E0 /* piBeaconProximityAlertViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = AEB0E8011870B8FE005475E0 /* piBeaconProximityAlertViewController.m */; };
34 | AEB0E8041870B8FE005475E0 /* piBeaconProximityAlertViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = AEB0E8021870B8FE005475E0 /* piBeaconProximityAlertViewController.xib */; };
35 | /* End PBXBuildFile section */
36 |
37 | /* Begin PBXContainerItemProxy section */
38 | AEB0E7D6186A7A83005475E0 /* PBXContainerItemProxy */ = {
39 | isa = PBXContainerItemProxy;
40 | containerPortal = AEB0E7A5186A7A83005475E0 /* Project object */;
41 | proxyType = 1;
42 | remoteGlobalIDString = AEB0E7AC186A7A83005475E0;
43 | remoteInfo = "piBeacon-iphone";
44 | };
45 | /* End PBXContainerItemProxy section */
46 |
47 | /* Begin PBXFileReference section */
48 | AEB0E7AD186A7A83005475E0 /* piBeacon-iphone.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "piBeacon-iphone.app"; sourceTree = BUILT_PRODUCTS_DIR; };
49 | AEB0E7B0186A7A83005475E0 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
50 | AEB0E7B2186A7A83005475E0 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
51 | AEB0E7B4186A7A83005475E0 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
52 | AEB0E7B8186A7A83005475E0 /* piBeacon-iphone-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "piBeacon-iphone-Info.plist"; sourceTree = ""; };
53 | AEB0E7BA186A7A83005475E0 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; };
54 | AEB0E7BC186A7A83005475E0 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
55 | AEB0E7BE186A7A83005475E0 /* piBeacon-iphone-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "piBeacon-iphone-Prefix.pch"; sourceTree = ""; };
56 | AEB0E7BF186A7A83005475E0 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
57 | AEB0E7C0186A7A83005475E0 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
58 | AEB0E7C3186A7A83005475E0 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
59 | AEB0E7C5186A7A83005475E0 /* FirstViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FirstViewController.h; sourceTree = ""; };
60 | AEB0E7C6186A7A83005475E0 /* FirstViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FirstViewController.m; sourceTree = ""; };
61 | AEB0E7C8186A7A83005475E0 /* SecondViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecondViewController.h; sourceTree = ""; };
62 | AEB0E7C9186A7A83005475E0 /* SecondViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SecondViewController.m; sourceTree = ""; };
63 | AEB0E7CB186A7A83005475E0 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; };
64 | AEB0E7D1186A7A83005475E0 /* piBeacon-iphoneTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "piBeacon-iphoneTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
65 | AEB0E7D2186A7A83005475E0 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; };
66 | AEB0E7DA186A7A83005475E0 /* piBeacon-iphoneTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "piBeacon-iphoneTests-Info.plist"; sourceTree = ""; };
67 | AEB0E7DC186A7A83005475E0 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; };
68 | AEB0E7DE186A7A83005475E0 /* piBeacon_iphoneTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = piBeacon_iphoneTests.m; sourceTree = ""; };
69 | AEB0E7E8186A7B82005475E0 /* CoreBluetooth.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreBluetooth.framework; path = System/Library/Frameworks/CoreBluetooth.framework; sourceTree = SDKROOT; };
70 | AEB0E7EA186A7B89005475E0 /* CoreLocation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreLocation.framework; path = System/Library/Frameworks/CoreLocation.framework; sourceTree = SDKROOT; };
71 | AEB0E7ED186C9324005475E0 /* ModelEngagement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ModelEngagement.h; sourceTree = ""; };
72 | AEB0E7EE186C9324005475E0 /* ModelEngagement.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ModelEngagement.m; sourceTree = ""; };
73 | AEB0E7F0186C94B3005475E0 /* piBeacon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = piBeacon.h; sourceTree = ""; };
74 | AEB0E7F1186C94B3005475E0 /* piBeacon.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = piBeacon.m; sourceTree = ""; };
75 | AEB0E7F6186CD9E8005475E0 /* piBeaconDetailViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = piBeaconDetailViewController.h; sourceTree = ""; };
76 | AEB0E7F7186CD9E8005475E0 /* piBeaconDetailViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = piBeaconDetailViewController.m; sourceTree = ""; };
77 | AEB0E7F8186CD9E8005475E0 /* piBeaconDetailViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = piBeaconDetailViewController.xib; sourceTree = ""; };
78 | AEB0E7FB186CDAE9005475E0 /* piBeaconUserDetailViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = piBeaconUserDetailViewController.h; sourceTree = ""; };
79 | AEB0E7FC186CDAE9005475E0 /* piBeaconUserDetailViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = piBeaconUserDetailViewController.m; sourceTree = ""; };
80 | AEB0E7FD186CDAE9005475E0 /* piBeaconUserDetailViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = piBeaconUserDetailViewController.xib; sourceTree = ""; };
81 | AEB0E8001870B8FE005475E0 /* piBeaconProximityAlertViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = piBeaconProximityAlertViewController.h; sourceTree = ""; };
82 | AEB0E8011870B8FE005475E0 /* piBeaconProximityAlertViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = piBeaconProximityAlertViewController.m; sourceTree = ""; };
83 | AEB0E8021870B8FE005475E0 /* piBeaconProximityAlertViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = piBeaconProximityAlertViewController.xib; sourceTree = ""; };
84 | /* End PBXFileReference section */
85 |
86 | /* Begin PBXFrameworksBuildPhase section */
87 | AEB0E7AA186A7A83005475E0 /* Frameworks */ = {
88 | isa = PBXFrameworksBuildPhase;
89 | buildActionMask = 2147483647;
90 | files = (
91 | AEB0E7EB186A7B89005475E0 /* CoreLocation.framework in Frameworks */,
92 | AEB0E7E9186A7B82005475E0 /* CoreBluetooth.framework in Frameworks */,
93 | AEB0E7B3186A7A83005475E0 /* CoreGraphics.framework in Frameworks */,
94 | AEB0E7B5186A7A83005475E0 /* UIKit.framework in Frameworks */,
95 | AEB0E7B1186A7A83005475E0 /* Foundation.framework in Frameworks */,
96 | );
97 | runOnlyForDeploymentPostprocessing = 0;
98 | };
99 | AEB0E7CE186A7A83005475E0 /* Frameworks */ = {
100 | isa = PBXFrameworksBuildPhase;
101 | buildActionMask = 2147483647;
102 | files = (
103 | AEB0E7D3186A7A83005475E0 /* XCTest.framework in Frameworks */,
104 | AEB0E7D5186A7A83005475E0 /* UIKit.framework in Frameworks */,
105 | AEB0E7D4186A7A83005475E0 /* Foundation.framework in Frameworks */,
106 | );
107 | runOnlyForDeploymentPostprocessing = 0;
108 | };
109 | /* End PBXFrameworksBuildPhase section */
110 |
111 | /* Begin PBXGroup section */
112 | AEB0E7A4186A7A83005475E0 = {
113 | isa = PBXGroup;
114 | children = (
115 | AEB0E7B6186A7A83005475E0 /* piBeacon-iphone */,
116 | AEB0E7D8186A7A83005475E0 /* piBeacon-iphoneTests */,
117 | AEB0E7AF186A7A83005475E0 /* Frameworks */,
118 | AEB0E7AE186A7A83005475E0 /* Products */,
119 | );
120 | sourceTree = "";
121 | };
122 | AEB0E7AE186A7A83005475E0 /* Products */ = {
123 | isa = PBXGroup;
124 | children = (
125 | AEB0E7AD186A7A83005475E0 /* piBeacon-iphone.app */,
126 | AEB0E7D1186A7A83005475E0 /* piBeacon-iphoneTests.xctest */,
127 | );
128 | name = Products;
129 | sourceTree = "";
130 | };
131 | AEB0E7AF186A7A83005475E0 /* Frameworks */ = {
132 | isa = PBXGroup;
133 | children = (
134 | AEB0E7EA186A7B89005475E0 /* CoreLocation.framework */,
135 | AEB0E7E8186A7B82005475E0 /* CoreBluetooth.framework */,
136 | AEB0E7B0186A7A83005475E0 /* Foundation.framework */,
137 | AEB0E7B2186A7A83005475E0 /* CoreGraphics.framework */,
138 | AEB0E7B4186A7A83005475E0 /* UIKit.framework */,
139 | AEB0E7D2186A7A83005475E0 /* XCTest.framework */,
140 | );
141 | name = Frameworks;
142 | sourceTree = "";
143 | };
144 | AEB0E7B6186A7A83005475E0 /* piBeacon-iphone */ = {
145 | isa = PBXGroup;
146 | children = (
147 | AEB0E7BF186A7A83005475E0 /* AppDelegate.h */,
148 | AEB0E7C0186A7A83005475E0 /* AppDelegate.m */,
149 | AEB0E7C2186A7A83005475E0 /* Main.storyboard */,
150 | AEB0E7C5186A7A83005475E0 /* FirstViewController.h */,
151 | AEB0E7C6186A7A83005475E0 /* FirstViewController.m */,
152 | AEB0E7C8186A7A83005475E0 /* SecondViewController.h */,
153 | AEB0E7C9186A7A83005475E0 /* SecondViewController.m */,
154 | AEB0E7EC186C9324005475E0 /* piBeacon */,
155 | AEB0E7CB186A7A83005475E0 /* Images.xcassets */,
156 | AEB0E7B7186A7A83005475E0 /* Supporting Files */,
157 | );
158 | path = "piBeacon-iphone";
159 | sourceTree = "";
160 | };
161 | AEB0E7B7186A7A83005475E0 /* Supporting Files */ = {
162 | isa = PBXGroup;
163 | children = (
164 | AEB0E7B8186A7A83005475E0 /* piBeacon-iphone-Info.plist */,
165 | AEB0E7B9186A7A83005475E0 /* InfoPlist.strings */,
166 | AEB0E7BC186A7A83005475E0 /* main.m */,
167 | AEB0E7BE186A7A83005475E0 /* piBeacon-iphone-Prefix.pch */,
168 | );
169 | name = "Supporting Files";
170 | sourceTree = "";
171 | };
172 | AEB0E7D8186A7A83005475E0 /* piBeacon-iphoneTests */ = {
173 | isa = PBXGroup;
174 | children = (
175 | AEB0E7DE186A7A83005475E0 /* piBeacon_iphoneTests.m */,
176 | AEB0E7D9186A7A83005475E0 /* Supporting Files */,
177 | );
178 | path = "piBeacon-iphoneTests";
179 | sourceTree = "";
180 | };
181 | AEB0E7D9186A7A83005475E0 /* Supporting Files */ = {
182 | isa = PBXGroup;
183 | children = (
184 | AEB0E7DA186A7A83005475E0 /* piBeacon-iphoneTests-Info.plist */,
185 | AEB0E7DB186A7A83005475E0 /* InfoPlist.strings */,
186 | );
187 | name = "Supporting Files";
188 | sourceTree = "";
189 | };
190 | AEB0E7EC186C9324005475E0 /* piBeacon */ = {
191 | isa = PBXGroup;
192 | children = (
193 | AEB0E7F0186C94B3005475E0 /* piBeacon.h */,
194 | AEB0E7F1186C94B3005475E0 /* piBeacon.m */,
195 | AEB0E7ED186C9324005475E0 /* ModelEngagement.h */,
196 | AEB0E7EE186C9324005475E0 /* ModelEngagement.m */,
197 | AEB0E7F6186CD9E8005475E0 /* piBeaconDetailViewController.h */,
198 | AEB0E7F7186CD9E8005475E0 /* piBeaconDetailViewController.m */,
199 | AEB0E7F8186CD9E8005475E0 /* piBeaconDetailViewController.xib */,
200 | AEB0E7FB186CDAE9005475E0 /* piBeaconUserDetailViewController.h */,
201 | AEB0E7FC186CDAE9005475E0 /* piBeaconUserDetailViewController.m */,
202 | AEB0E7FD186CDAE9005475E0 /* piBeaconUserDetailViewController.xib */,
203 | AEB0E8001870B8FE005475E0 /* piBeaconProximityAlertViewController.h */,
204 | AEB0E8011870B8FE005475E0 /* piBeaconProximityAlertViewController.m */,
205 | AEB0E8021870B8FE005475E0 /* piBeaconProximityAlertViewController.xib */,
206 | );
207 | path = piBeacon;
208 | sourceTree = "";
209 | };
210 | /* End PBXGroup section */
211 |
212 | /* Begin PBXNativeTarget section */
213 | AEB0E7AC186A7A83005475E0 /* piBeacon-iphone */ = {
214 | isa = PBXNativeTarget;
215 | buildConfigurationList = AEB0E7E2186A7A83005475E0 /* Build configuration list for PBXNativeTarget "piBeacon-iphone" */;
216 | buildPhases = (
217 | AEB0E7A9186A7A83005475E0 /* Sources */,
218 | AEB0E7AA186A7A83005475E0 /* Frameworks */,
219 | AEB0E7AB186A7A83005475E0 /* Resources */,
220 | );
221 | buildRules = (
222 | );
223 | dependencies = (
224 | );
225 | name = "piBeacon-iphone";
226 | productName = "piBeacon-iphone";
227 | productReference = AEB0E7AD186A7A83005475E0 /* piBeacon-iphone.app */;
228 | productType = "com.apple.product-type.application";
229 | };
230 | AEB0E7D0186A7A83005475E0 /* piBeacon-iphoneTests */ = {
231 | isa = PBXNativeTarget;
232 | buildConfigurationList = AEB0E7E5186A7A83005475E0 /* Build configuration list for PBXNativeTarget "piBeacon-iphoneTests" */;
233 | buildPhases = (
234 | AEB0E7CD186A7A83005475E0 /* Sources */,
235 | AEB0E7CE186A7A83005475E0 /* Frameworks */,
236 | AEB0E7CF186A7A83005475E0 /* Resources */,
237 | );
238 | buildRules = (
239 | );
240 | dependencies = (
241 | AEB0E7D7186A7A83005475E0 /* PBXTargetDependency */,
242 | );
243 | name = "piBeacon-iphoneTests";
244 | productName = "piBeacon-iphoneTests";
245 | productReference = AEB0E7D1186A7A83005475E0 /* piBeacon-iphoneTests.xctest */;
246 | productType = "com.apple.product-type.bundle.unit-test";
247 | };
248 | /* End PBXNativeTarget section */
249 |
250 | /* Begin PBXProject section */
251 | AEB0E7A5186A7A83005475E0 /* Project object */ = {
252 | isa = PBXProject;
253 | attributes = {
254 | LastUpgradeCheck = 0500;
255 | ORGANIZATIONNAME = "Matt Schmulen";
256 | TargetAttributes = {
257 | AEB0E7AC186A7A83005475E0 = {
258 | SystemCapabilities = {
259 | com.apple.BackgroundModes = {
260 | enabled = 1;
261 | };
262 | };
263 | };
264 | AEB0E7D0186A7A83005475E0 = {
265 | TestTargetID = AEB0E7AC186A7A83005475E0;
266 | };
267 | };
268 | };
269 | buildConfigurationList = AEB0E7A8186A7A83005475E0 /* Build configuration list for PBXProject "piBeacon-iphone" */;
270 | compatibilityVersion = "Xcode 3.2";
271 | developmentRegion = English;
272 | hasScannedForEncodings = 0;
273 | knownRegions = (
274 | en,
275 | Base,
276 | );
277 | mainGroup = AEB0E7A4186A7A83005475E0;
278 | productRefGroup = AEB0E7AE186A7A83005475E0 /* Products */;
279 | projectDirPath = "";
280 | projectRoot = "";
281 | targets = (
282 | AEB0E7AC186A7A83005475E0 /* piBeacon-iphone */,
283 | AEB0E7D0186A7A83005475E0 /* piBeacon-iphoneTests */,
284 | );
285 | };
286 | /* End PBXProject section */
287 |
288 | /* Begin PBXResourcesBuildPhase section */
289 | AEB0E7AB186A7A83005475E0 /* Resources */ = {
290 | isa = PBXResourcesBuildPhase;
291 | buildActionMask = 2147483647;
292 | files = (
293 | AEB0E8041870B8FE005475E0 /* piBeaconProximityAlertViewController.xib in Resources */,
294 | AEB0E7FA186CD9E8005475E0 /* piBeaconDetailViewController.xib in Resources */,
295 | AEB0E7CC186A7A83005475E0 /* Images.xcassets in Resources */,
296 | AEB0E7BB186A7A83005475E0 /* InfoPlist.strings in Resources */,
297 | AEB0E7C4186A7A83005475E0 /* Main.storyboard in Resources */,
298 | AEB0E7FF186CDAE9005475E0 /* piBeaconUserDetailViewController.xib in Resources */,
299 | );
300 | runOnlyForDeploymentPostprocessing = 0;
301 | };
302 | AEB0E7CF186A7A83005475E0 /* Resources */ = {
303 | isa = PBXResourcesBuildPhase;
304 | buildActionMask = 2147483647;
305 | files = (
306 | AEB0E7DD186A7A83005475E0 /* InfoPlist.strings in Resources */,
307 | );
308 | runOnlyForDeploymentPostprocessing = 0;
309 | };
310 | /* End PBXResourcesBuildPhase section */
311 |
312 | /* Begin PBXSourcesBuildPhase section */
313 | AEB0E7A9186A7A83005475E0 /* Sources */ = {
314 | isa = PBXSourcesBuildPhase;
315 | buildActionMask = 2147483647;
316 | files = (
317 | AEB0E7FE186CDAE9005475E0 /* piBeaconUserDetailViewController.m in Sources */,
318 | AEB0E7CA186A7A83005475E0 /* SecondViewController.m in Sources */,
319 | AEB0E7C1186A7A83005475E0 /* AppDelegate.m in Sources */,
320 | AEB0E7C7186A7A83005475E0 /* FirstViewController.m in Sources */,
321 | AEB0E7F9186CD9E8005475E0 /* piBeaconDetailViewController.m in Sources */,
322 | AEB0E7EF186C9324005475E0 /* ModelEngagement.m in Sources */,
323 | AEB0E8031870B8FE005475E0 /* piBeaconProximityAlertViewController.m in Sources */,
324 | AEB0E7F2186C94B3005475E0 /* piBeacon.m in Sources */,
325 | AEB0E7BD186A7A83005475E0 /* main.m in Sources */,
326 | );
327 | runOnlyForDeploymentPostprocessing = 0;
328 | };
329 | AEB0E7CD186A7A83005475E0 /* Sources */ = {
330 | isa = PBXSourcesBuildPhase;
331 | buildActionMask = 2147483647;
332 | files = (
333 | AEB0E7DF186A7A83005475E0 /* piBeacon_iphoneTests.m in Sources */,
334 | );
335 | runOnlyForDeploymentPostprocessing = 0;
336 | };
337 | /* End PBXSourcesBuildPhase section */
338 |
339 | /* Begin PBXTargetDependency section */
340 | AEB0E7D7186A7A83005475E0 /* PBXTargetDependency */ = {
341 | isa = PBXTargetDependency;
342 | target = AEB0E7AC186A7A83005475E0 /* piBeacon-iphone */;
343 | targetProxy = AEB0E7D6186A7A83005475E0 /* PBXContainerItemProxy */;
344 | };
345 | /* End PBXTargetDependency section */
346 |
347 | /* Begin PBXVariantGroup section */
348 | AEB0E7B9186A7A83005475E0 /* InfoPlist.strings */ = {
349 | isa = PBXVariantGroup;
350 | children = (
351 | AEB0E7BA186A7A83005475E0 /* en */,
352 | );
353 | name = InfoPlist.strings;
354 | sourceTree = "";
355 | };
356 | AEB0E7C2186A7A83005475E0 /* Main.storyboard */ = {
357 | isa = PBXVariantGroup;
358 | children = (
359 | AEB0E7C3186A7A83005475E0 /* Base */,
360 | );
361 | name = Main.storyboard;
362 | sourceTree = "";
363 | };
364 | AEB0E7DB186A7A83005475E0 /* InfoPlist.strings */ = {
365 | isa = PBXVariantGroup;
366 | children = (
367 | AEB0E7DC186A7A83005475E0 /* en */,
368 | );
369 | name = InfoPlist.strings;
370 | sourceTree = "";
371 | };
372 | /* End PBXVariantGroup section */
373 |
374 | /* Begin XCBuildConfiguration section */
375 | AEB0E7E0186A7A83005475E0 /* Debug */ = {
376 | isa = XCBuildConfiguration;
377 | buildSettings = {
378 | ALWAYS_SEARCH_USER_PATHS = NO;
379 | ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)";
380 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
381 | CLANG_CXX_LIBRARY = "libc++";
382 | CLANG_ENABLE_MODULES = YES;
383 | CLANG_ENABLE_OBJC_ARC = YES;
384 | CLANG_WARN_BOOL_CONVERSION = YES;
385 | CLANG_WARN_CONSTANT_CONVERSION = YES;
386 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
387 | CLANG_WARN_EMPTY_BODY = YES;
388 | CLANG_WARN_ENUM_CONVERSION = YES;
389 | CLANG_WARN_INT_CONVERSION = YES;
390 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
391 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
392 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
393 | COPY_PHASE_STRIP = NO;
394 | GCC_C_LANGUAGE_STANDARD = gnu99;
395 | GCC_DYNAMIC_NO_PIC = NO;
396 | GCC_OPTIMIZATION_LEVEL = 0;
397 | GCC_PREPROCESSOR_DEFINITIONS = (
398 | "DEBUG=1",
399 | "$(inherited)",
400 | );
401 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
402 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
403 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
404 | GCC_WARN_UNDECLARED_SELECTOR = YES;
405 | GCC_WARN_UNINITIALIZED_AUTOS = YES;
406 | GCC_WARN_UNUSED_FUNCTION = YES;
407 | GCC_WARN_UNUSED_VARIABLE = YES;
408 | IPHONEOS_DEPLOYMENT_TARGET = 7.0;
409 | ONLY_ACTIVE_ARCH = YES;
410 | SDKROOT = iphoneos;
411 | };
412 | name = Debug;
413 | };
414 | AEB0E7E1186A7A83005475E0 /* Release */ = {
415 | isa = XCBuildConfiguration;
416 | buildSettings = {
417 | ALWAYS_SEARCH_USER_PATHS = NO;
418 | ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)";
419 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
420 | CLANG_CXX_LIBRARY = "libc++";
421 | CLANG_ENABLE_MODULES = YES;
422 | CLANG_ENABLE_OBJC_ARC = YES;
423 | CLANG_WARN_BOOL_CONVERSION = YES;
424 | CLANG_WARN_CONSTANT_CONVERSION = YES;
425 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
426 | CLANG_WARN_EMPTY_BODY = YES;
427 | CLANG_WARN_ENUM_CONVERSION = YES;
428 | CLANG_WARN_INT_CONVERSION = YES;
429 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
430 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
431 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
432 | COPY_PHASE_STRIP = YES;
433 | ENABLE_NS_ASSERTIONS = NO;
434 | GCC_C_LANGUAGE_STANDARD = gnu99;
435 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
436 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
437 | GCC_WARN_UNDECLARED_SELECTOR = YES;
438 | GCC_WARN_UNINITIALIZED_AUTOS = YES;
439 | GCC_WARN_UNUSED_FUNCTION = YES;
440 | GCC_WARN_UNUSED_VARIABLE = YES;
441 | IPHONEOS_DEPLOYMENT_TARGET = 7.0;
442 | SDKROOT = iphoneos;
443 | VALIDATE_PRODUCT = YES;
444 | };
445 | name = Release;
446 | };
447 | AEB0E7E3186A7A83005475E0 /* Debug */ = {
448 | isa = XCBuildConfiguration;
449 | buildSettings = {
450 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
451 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
452 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
453 | GCC_PREFIX_HEADER = "piBeacon-iphone/piBeacon-iphone-Prefix.pch";
454 | INFOPLIST_FILE = "piBeacon-iphone/piBeacon-iphone-Info.plist";
455 | PRODUCT_NAME = "$(TARGET_NAME)";
456 | WRAPPER_EXTENSION = app;
457 | };
458 | name = Debug;
459 | };
460 | AEB0E7E4186A7A83005475E0 /* Release */ = {
461 | isa = XCBuildConfiguration;
462 | buildSettings = {
463 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
464 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
465 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
466 | GCC_PREFIX_HEADER = "piBeacon-iphone/piBeacon-iphone-Prefix.pch";
467 | INFOPLIST_FILE = "piBeacon-iphone/piBeacon-iphone-Info.plist";
468 | PRODUCT_NAME = "$(TARGET_NAME)";
469 | WRAPPER_EXTENSION = app;
470 | };
471 | name = Release;
472 | };
473 | AEB0E7E6186A7A83005475E0 /* Debug */ = {
474 | isa = XCBuildConfiguration;
475 | buildSettings = {
476 | ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)";
477 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/piBeacon-iphone.app/piBeacon-iphone";
478 | FRAMEWORK_SEARCH_PATHS = (
479 | "$(SDKROOT)/Developer/Library/Frameworks",
480 | "$(inherited)",
481 | "$(DEVELOPER_FRAMEWORKS_DIR)",
482 | );
483 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
484 | GCC_PREFIX_HEADER = "piBeacon-iphone/piBeacon-iphone-Prefix.pch";
485 | GCC_PREPROCESSOR_DEFINITIONS = (
486 | "DEBUG=1",
487 | "$(inherited)",
488 | );
489 | INFOPLIST_FILE = "piBeacon-iphoneTests/piBeacon-iphoneTests-Info.plist";
490 | PRODUCT_NAME = "$(TARGET_NAME)";
491 | TEST_HOST = "$(BUNDLE_LOADER)";
492 | WRAPPER_EXTENSION = xctest;
493 | };
494 | name = Debug;
495 | };
496 | AEB0E7E7186A7A83005475E0 /* Release */ = {
497 | isa = XCBuildConfiguration;
498 | buildSettings = {
499 | ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)";
500 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/piBeacon-iphone.app/piBeacon-iphone";
501 | FRAMEWORK_SEARCH_PATHS = (
502 | "$(SDKROOT)/Developer/Library/Frameworks",
503 | "$(inherited)",
504 | "$(DEVELOPER_FRAMEWORKS_DIR)",
505 | );
506 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
507 | GCC_PREFIX_HEADER = "piBeacon-iphone/piBeacon-iphone-Prefix.pch";
508 | INFOPLIST_FILE = "piBeacon-iphoneTests/piBeacon-iphoneTests-Info.plist";
509 | PRODUCT_NAME = "$(TARGET_NAME)";
510 | TEST_HOST = "$(BUNDLE_LOADER)";
511 | WRAPPER_EXTENSION = xctest;
512 | };
513 | name = Release;
514 | };
515 | /* End XCBuildConfiguration section */
516 |
517 | /* Begin XCConfigurationList section */
518 | AEB0E7A8186A7A83005475E0 /* Build configuration list for PBXProject "piBeacon-iphone" */ = {
519 | isa = XCConfigurationList;
520 | buildConfigurations = (
521 | AEB0E7E0186A7A83005475E0 /* Debug */,
522 | AEB0E7E1186A7A83005475E0 /* Release */,
523 | );
524 | defaultConfigurationIsVisible = 0;
525 | defaultConfigurationName = Release;
526 | };
527 | AEB0E7E2186A7A83005475E0 /* Build configuration list for PBXNativeTarget "piBeacon-iphone" */ = {
528 | isa = XCConfigurationList;
529 | buildConfigurations = (
530 | AEB0E7E3186A7A83005475E0 /* Debug */,
531 | AEB0E7E4186A7A83005475E0 /* Release */,
532 | );
533 | defaultConfigurationIsVisible = 0;
534 | defaultConfigurationName = Release;
535 | };
536 | AEB0E7E5186A7A83005475E0 /* Build configuration list for PBXNativeTarget "piBeacon-iphoneTests" */ = {
537 | isa = XCConfigurationList;
538 | buildConfigurations = (
539 | AEB0E7E6186A7A83005475E0 /* Debug */,
540 | AEB0E7E7186A7A83005475E0 /* Release */,
541 | );
542 | defaultConfigurationIsVisible = 0;
543 | defaultConfigurationName = Release;
544 | };
545 | /* End XCConfigurationList section */
546 | };
547 | rootObject = AEB0E7A5186A7A83005475E0 /* Project object */;
548 | }
549 |
--------------------------------------------------------------------------------
/client-iphone/piBeacon-iphone.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/client-iphone/piBeacon-iphone.xcodeproj/project.xcworkspace/xcuserdata/matt.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mschmulen/tracking-bluetooth-ibeacons-with-node/2798b01ac4af5ff7ad8a46019ea8ea1b8178d6a2/client-iphone/piBeacon-iphone.xcodeproj/project.xcworkspace/xcuserdata/matt.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/client-iphone/piBeacon-iphone.xcodeproj/xcuserdata/matt.xcuserdatad/xcschemes/piBeacon-iphone.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
33 |
39 |
40 |
41 |
42 |
43 |
49 |
50 |
51 |
52 |
61 |
62 |
68 |
69 |
70 |
71 |
72 |
73 |
79 |
80 |
86 |
87 |
88 |
89 |
91 |
92 |
95 |
96 |
97 |
--------------------------------------------------------------------------------
/client-iphone/piBeacon-iphone.xcodeproj/xcuserdata/matt.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | piBeacon-iphone.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | AEB0E7AC186A7A83005475E0
16 |
17 | primary
18 |
19 |
20 | AEB0E7D0186A7A83005475E0
21 |
22 | primary
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/client-iphone/piBeacon-iphone/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // piBeacon-iphone
4 | //
5 | // Created by Matt Schmulen on 12/24/13.
6 | // Copyright (c) 2013 Matt Schmulen. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface AppDelegate : UIResponder
12 |
13 | @property (strong, nonatomic) UIWindow *window;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/client-iphone/piBeacon-iphone/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // piBeacon-iphone
4 | //
5 | // Created by Matt Schmulen on 12/24/13.
6 | // Copyright (c) 2013 Matt Schmulen. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 |
11 | @implementation AppDelegate
12 |
13 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
14 | {
15 | // Override point for customization after application launch.
16 | return YES;
17 | }
18 |
19 | - (void)applicationWillResignActive:(UIApplication *)application
20 | {
21 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
22 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
23 | }
24 |
25 | - (void)applicationDidEnterBackground:(UIApplication *)application
26 | {
27 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
28 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
29 | }
30 |
31 | - (void)applicationWillEnterForeground:(UIApplication *)application
32 | {
33 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
34 | }
35 |
36 | - (void)applicationDidBecomeActive:(UIApplication *)application
37 | {
38 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
39 | }
40 |
41 | - (void)applicationWillTerminate:(UIApplication *)application
42 | {
43 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
44 | }
45 |
46 | @end
47 |
--------------------------------------------------------------------------------
/client-iphone/piBeacon-iphone/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
49 |
55 |
61 |
68 |
69 |
70 |
71 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
119 |
125 |
126 |
127 |
128 |
129 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
--------------------------------------------------------------------------------
/client-iphone/piBeacon-iphone/FirstViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // FirstViewController.h
3 | // piBeacon-iphone
4 | //
5 | // Created by Matt Schmulen on 12/24/13.
6 | // Copyright (c) 2013 Matt Schmulen. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "piBeacon.h"
11 |
12 | @interface FirstViewController : UIViewController
13 |
14 | @end
15 |
--------------------------------------------------------------------------------
/client-iphone/piBeacon-iphone/FirstViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // FirstViewController.m
3 | // piBeacon-iphone
4 | //
5 | // Created by Matt Schmulen on 12/24/13.
6 | // Copyright (c) 2013 Matt Schmulen. All rights reserved.
7 | //
8 |
9 | #import "FirstViewController.h"
10 |
11 | @interface FirstViewController ()
12 |
13 | @property ( nonatomic ) UIDynamicAnimator* animator;
14 | @property ( nonatomic ) UIGravityBehavior* gravity;
15 | @property ( nonatomic ) UICollisionBehavior* collisionBehavior;
16 |
17 | @end
18 |
19 | @implementation FirstViewController
20 |
21 | - (IBAction)actionTest:(id)sender {
22 | NSLog(@"action Test");
23 |
24 | [piBeacon simulateProximityEvent];
25 |
26 | // piBeaconProximityAlertViewController* vController = [[piBeaconProximityAlertViewController alloc] init];
27 | //[self presentViewController:vController animated:YES completion:nil];
28 | }
29 |
30 | - (void) receiveNewEngagementNotification:(NSNotification *) notification
31 | {
32 | NSLog (@"Successfully received notification!");
33 |
34 | if ([[notification name] isEqualToString:notification_NewEngagement]){
35 | NSLog (@"Successfully received the engagement notification!");
36 |
37 | piBeaconProximityAlertViewController* vController = [[piBeaconProximityAlertViewController alloc] init];
38 | [self presentViewController:vController animated:YES completion:nil];
39 | }
40 |
41 | //ModelEngagement *engagement = notification.object;
42 | //[self.tableData addObject:engagement];
43 | //[self.myTableView reloadData];
44 | }
45 |
46 | -(void)collisionBehavior:(UICollisionBehavior *)behavior beganContactForItem:(id)item withBoundaryIdentifier:(id)identifier atPoint:(CGPoint)p
47 | {
48 | // Lighten the background color when the view is in contact with a boundary.
49 | [(UIView*)item setBackgroundColor:[UIColor lightGrayColor]];
50 | }
51 |
52 |
53 | -(void)collisionBehavior:(UICollisionBehavior *)behavior endedContactForItem:(id)item withBoundaryIdentifier:(id)identifier
54 | {
55 | // Restore the default color when ending a contcact.
56 | [(UIView*)item setBackgroundColor:[UIColor grayColor]];
57 | }
58 |
59 | - (void)viewDidLoad
60 | {
61 | [super viewDidLoad];
62 | // Do any additional setup after loading the view, typically from a nib.
63 |
64 | //[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receiveNewEngagementNotification:) name:notification_NewEngagement object:nil];
65 |
66 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receiveNewEngagementNotification:) name:notification_NewEngagement object:nil];
67 |
68 | // ------------------
69 | //Configure dynamics
70 | //configure
71 | //_animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
72 | //_gravity = [[UIGravityBehavior alloc] initWithItems:@[self.imageViewBeaconNotify]];
73 |
74 | //configure the collision behavior
75 | //_collisionBehavior = [[UICollisionBehavior alloc] initWithItems:@[self.imageViewBeaconNotify]];
76 | //_collisionBehavior.translatesReferenceBoundsIntoBoundary = YES;
77 |
78 | //run the animation
79 | //[_animator addBehavior:_gravity];
80 | //[_animator addBehavior:_collisionBehavior];
81 | //_collisionBehavior.collisionDelegate = self;
82 | // ------------------
83 |
84 | }
85 |
86 | - (void)didReceiveMemoryWarning
87 | {
88 | [super didReceiveMemoryWarning];
89 | // Dispose of any resources that can be recreated.
90 | }
91 |
92 | @end
93 |
--------------------------------------------------------------------------------
/client-iphone/piBeacon-iphone/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "40x40",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "60x60",
16 | "scale" : "2x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/client-iphone/piBeacon-iphone/Images.xcassets/LaunchImage.launchimage/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "orientation" : "portrait",
5 | "idiom" : "iphone",
6 | "extent" : "full-screen",
7 | "minimum-system-version" : "7.0",
8 | "scale" : "2x"
9 | },
10 | {
11 | "orientation" : "portrait",
12 | "idiom" : "iphone",
13 | "subtype" : "retina4",
14 | "extent" : "full-screen",
15 | "minimum-system-version" : "7.0",
16 | "scale" : "2x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/client-iphone/piBeacon-iphone/Images.xcassets/first.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "first.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x",
11 | "filename" : "first@2x.png"
12 | }
13 | ],
14 | "info" : {
15 | "version" : 1,
16 | "author" : "xcode"
17 | }
18 | }
--------------------------------------------------------------------------------
/client-iphone/piBeacon-iphone/Images.xcassets/first.imageset/first.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mschmulen/tracking-bluetooth-ibeacons-with-node/2798b01ac4af5ff7ad8a46019ea8ea1b8178d6a2/client-iphone/piBeacon-iphone/Images.xcassets/first.imageset/first.png
--------------------------------------------------------------------------------
/client-iphone/piBeacon-iphone/Images.xcassets/first.imageset/first@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mschmulen/tracking-bluetooth-ibeacons-with-node/2798b01ac4af5ff7ad8a46019ea8ea1b8178d6a2/client-iphone/piBeacon-iphone/Images.xcassets/first.imageset/first@2x.png
--------------------------------------------------------------------------------
/client-iphone/piBeacon-iphone/Images.xcassets/second.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "second.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x",
11 | "filename" : "second@2x.png"
12 | }
13 | ],
14 | "info" : {
15 | "version" : 1,
16 | "author" : "xcode"
17 | }
18 | }
--------------------------------------------------------------------------------
/client-iphone/piBeacon-iphone/Images.xcassets/second.imageset/second.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mschmulen/tracking-bluetooth-ibeacons-with-node/2798b01ac4af5ff7ad8a46019ea8ea1b8178d6a2/client-iphone/piBeacon-iphone/Images.xcassets/second.imageset/second.png
--------------------------------------------------------------------------------
/client-iphone/piBeacon-iphone/Images.xcassets/second.imageset/second@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mschmulen/tracking-bluetooth-ibeacons-with-node/2798b01ac4af5ff7ad8a46019ea8ea1b8178d6a2/client-iphone/piBeacon-iphone/Images.xcassets/second.imageset/second@2x.png
--------------------------------------------------------------------------------
/client-iphone/piBeacon-iphone/Images.xcassets/unknown-user.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "unknown-user.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | }
12 | ],
13 | "info" : {
14 | "version" : 1,
15 | "author" : "xcode"
16 | }
17 | }
--------------------------------------------------------------------------------
/client-iphone/piBeacon-iphone/Images.xcassets/unknown-user.imageset/unknown-user.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mschmulen/tracking-bluetooth-ibeacons-with-node/2798b01ac4af5ff7ad8a46019ea8ea1b8178d6a2/client-iphone/piBeacon-iphone/Images.xcassets/unknown-user.imageset/unknown-user.png
--------------------------------------------------------------------------------
/client-iphone/piBeacon-iphone/SecondViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // SecondViewController.h
3 | // piBeacon-iphone
4 | //
5 | // Created by Matt Schmulen on 12/24/13.
6 | // Copyright (c) 2013 Matt Schmulen. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 | #import
12 |
13 | @interface SecondViewController : UIViewController < UITableViewDelegate, UITableViewDataSource, CLLocationManagerDelegate, CBPeripheralManagerDelegate>
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/client-iphone/piBeacon-iphone/SecondViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // SecondViewController.m
3 | // piBeacon-iphone
4 | //
5 | // Created by Matt Schmulen on 12/24/13.
6 | // Copyright (c) 2013 Matt Schmulen. All rights reserved.
7 | //
8 |
9 | #import "SecondViewController.h"
10 | #import "piBeacon.h"
11 |
12 | // TableView Cell Identifier
13 | static NSString * const kCellIdentifier = @"iBeaconCell";
14 |
15 | @interface SecondViewController ()
16 |
17 | @property (weak, nonatomic) IBOutlet UISwitch *switchAdvertising;
18 | @property (weak, nonatomic) IBOutlet UISwitch *switchRanging;
19 | @property (weak, nonatomic) IBOutlet UITextField *textFieldUUID;
20 | @property (weak, nonatomic) IBOutlet UITextField *textFieldBeaconRegionID;
21 | @property (weak, nonatomic) IBOutlet UITableView *myTableView;
22 |
23 |
24 | @property (strong, nonatomic) piBeacon *piBeacon;
25 |
26 | @property ( strong, nonatomic ) NSArray *tableData;
27 | @property (nonatomic, strong) CLBeaconRegion *beaconRegion;
28 | @property (nonatomic, strong) CBPeripheralManager *peripheralManager;
29 | @property (nonatomic, strong) CLLocationManager *locationManager;
30 |
31 | @end
32 |
33 | @implementation SecondViewController
34 |
35 | - (NSArray *) tableData
36 | {
37 | if (! _tableData ) _tableData = [[NSArray alloc] init];
38 | return _tableData;
39 | }
40 |
41 | - (piBeacon *) piBeacon
42 | {
43 | if (! _piBeacon ) {
44 | _piBeacon = [[piBeacon alloc] init];
45 | [_piBeacon initWithConfig:@"87209302-C7F2-4D56-B1D1-14EADD0CE41F" beaconRegionId:@"org.pibeacon" beaconMajor:1 beaconMinor:1];
46 | }
47 | return _piBeacon;
48 | }
49 |
50 |
51 |
52 | #pragma mark - Beacon ranging
53 | - (void)createBeaconRegion
54 | {
55 | if (self.beaconRegion)
56 | return;
57 |
58 | NSUUID *proximityUUID = [[NSUUID alloc] initWithUUIDString:self.piBeacon.piUUID];
59 | self.beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:proximityUUID identifier:self.piBeacon.piRegionIdentifier];
60 | }
61 |
62 | - (void)turnOnRanging
63 | {
64 | if (![CLLocationManager isRangingAvailable]) {
65 | self.switchRanging.on = NO;
66 | return;
67 | }
68 | if (self.locationManager.rangedRegions.count > 0) {
69 | return;
70 | }
71 |
72 | [self createBeaconRegion];
73 | [self.locationManager startRangingBeaconsInRegion:self.beaconRegion];
74 | }
75 |
76 |
77 | - (void)changeRangingState:sender
78 | {
79 | UISwitch *theSwitch = (UISwitch *)sender;
80 | if (theSwitch.on) {
81 | [self startRangingForBeacons];
82 | } else {
83 | [self stopRangingForBeacons];
84 | }
85 | }
86 |
87 | - (void)startRangingForBeacons
88 | {
89 | self.locationManager = [[CLLocationManager alloc] init];
90 | self.locationManager.delegate = self;
91 | self.locationManager.activityType = CLActivityTypeFitness;
92 | self.locationManager.distanceFilter = kCLDistanceFilterNone;
93 | self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
94 |
95 | [self turnOnRanging];
96 | }
97 |
98 | - (void)stopRangingForBeacons
99 | {
100 | if (self.locationManager.rangedRegions.count == 0) {
101 | return;
102 | }
103 |
104 | [self.locationManager stopRangingBeaconsInRegion:self.beaconRegion];
105 |
106 | self.tableData = nil;
107 | [self.myTableView reloadData];
108 | }
109 |
110 | #pragma mark - Beacon ranging delegate methods
111 | - (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
112 | {
113 | if (![CLLocationManager locationServicesEnabled]) {
114 | self.switchRanging.on = NO;
115 | return;
116 | }
117 |
118 | if ([CLLocationManager authorizationStatus] != kCLAuthorizationStatusAuthorized) {
119 | self.switchRanging.on = NO;
120 | return;
121 | }
122 |
123 | self.switchRanging.on = YES;
124 | }
125 |
126 | - (void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons
127 | inRegion:(CLBeaconRegion *)region {
128 |
129 | if ([beacons count] == 0) {
130 | //NSLog(@"No beacons found nearby.");
131 | } else {
132 | //NSLog(@"Found beacons! %@", region.identifier);
133 | }
134 |
135 | //MAS Todo startEngagement
136 | // ModelEngagement *engagement = [self engagementFactory:self.piBeacon.piUUID];
137 | // engagement.iBeaconRegionIdentifier = region.identifier;
138 |
139 | self.tableData = beacons;
140 | [self.myTableView reloadData];
141 | }
142 |
143 | #pragma mark - Beacon advertising
144 | - (void)turnOnAdvertising
145 | {
146 | if (self.peripheralManager.state != 5) {
147 | self.switchAdvertising.on = NO;
148 | return;
149 | }
150 |
151 | CLBeaconRegion *region = [[CLBeaconRegion alloc] initWithProximityUUID:self.beaconRegion.proximityUUID
152 | major: self.piBeacon.piMajor
153 | minor: self.piBeacon.piMinor
154 | identifier:self.beaconRegion.identifier];
155 |
156 | NSDictionary *beaconPeripheralData = [region peripheralDataWithMeasuredPower:nil];
157 | [self.peripheralManager startAdvertising:beaconPeripheralData];
158 | }
159 |
160 |
161 | - (void)changeAdvertisingState:sender
162 | {
163 | UISwitch *theSwitch = (UISwitch *)sender;
164 | if (theSwitch.on) {
165 | [self startAdvertisingBeacon];
166 | } else {
167 | [self stopAdvertisingBeacon];
168 | }
169 | }
170 |
171 |
172 | - (void)startAdvertisingBeacon
173 | {
174 | [self createBeaconRegion];
175 |
176 | if (!self.peripheralManager)
177 | self.peripheralManager = [[CBPeripheralManager alloc] initWithDelegate:self queue:nil options:nil];
178 |
179 | [self turnOnAdvertising];
180 | }
181 |
182 | - (void)stopAdvertisingBeacon
183 | {
184 | [self.peripheralManager stopAdvertising];
185 | }
186 |
187 | #pragma mark - Beacon advertising delegate methods
188 | - (void)peripheralManagerDidStartAdvertising:(CBPeripheralManager *)peripheralManager error:(NSError *)error
189 | {
190 | if (error) {
191 | self.switchAdvertising.on = NO;
192 | return;
193 | }
194 |
195 | if (peripheralManager.isAdvertising) {
196 | self.switchAdvertising.on = YES;
197 | }
198 | }
199 |
200 | - (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheralManager
201 | {
202 | if (peripheralManager.state != 5) {
203 | self.switchAdvertising.on = NO;
204 | return;
205 | }
206 | [self turnOnAdvertising];
207 | }
208 |
209 |
210 | #pragma mark - UITableView Delegate
211 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
212 | {
213 | return [self.tableData count];
214 | }
215 |
216 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
217 | {
218 | CLBeacon *beacon = self.tableData[indexPath.row];
219 |
220 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier];
221 |
222 | if (cell == nil) {
223 | cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:kCellIdentifier];
224 | }
225 |
226 | cell.textLabel.text = beacon.proximityUUID.UUIDString;
227 |
228 | NSString *proximityString;
229 | switch (beacon.proximity) {
230 | case CLProximityNear:
231 | proximityString = @"Near";
232 | break;
233 | case CLProximityImmediate:
234 | proximityString = @"Immediate";
235 | break;
236 | case CLProximityFar:
237 | proximityString = @"Far";
238 | break;
239 | case CLProximityUnknown:
240 | default:
241 | proximityString = @"Unknown";
242 | break;
243 | }
244 | cell.detailTextLabel.text = [NSString stringWithFormat:@"%@, %@ • %@ • %f • %li",
245 | beacon.major.stringValue,
246 | beacon.minor.stringValue,
247 | proximityString,
248 | beacon.accuracy,
249 | (long)beacon.rssi];
250 | cell.detailTextLabel.textColor = [UIColor grayColor];
251 | return cell;
252 | }
253 |
254 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
255 |
256 | piBeaconDetailViewController *detailController = [[piBeaconDetailViewController alloc] init];
257 | detailController.model = [self.tableData objectAtIndex:indexPath.row];
258 | [self.tabBarController presentViewController: detailController animated:YES completion:nil];
259 |
260 | }
261 |
262 | -(void) tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
263 | {
264 | //myCell *cell = [tableView cellForRowAtIndexPath:indexPath];
265 | //cell.customHelpButton.hidden = true;
266 |
267 | piBeaconDetailViewController *detailController = [[piBeaconDetailViewController alloc] init];
268 | detailController.model = [self.tableData objectAtIndex:indexPath.row];
269 | [self.tabBarController presentViewController: detailController animated:YES completion:nil];
270 | }
271 |
272 | /*
273 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
274 | {
275 | if ([segue.identifier isEqualToString:@"showDetail"]) {
276 |
277 | NSInteger row = [[self myTableView].indexPathForSelectedRow row];
278 | NSObject *rowObject = [[self tableData] objectAtIndex:row];
279 |
280 | piBeaconDetailViewController *detailController = segue.destinationViewController;
281 | detailController.model = rowObject;
282 | }
283 | }
284 | */
285 |
286 |
287 | - (void)viewDidLoad
288 | {
289 | [super viewDidLoad];
290 |
291 | self.textFieldUUID.text = self.piBeacon.piUUID;
292 | self.textFieldBeaconRegionID.text = self.piBeacon.piRegionIdentifier;
293 |
294 | [self.switchAdvertising addTarget:self action:@selector(changeAdvertisingState:) forControlEvents:UIControlEventValueChanged];
295 | [self.switchRanging addTarget:self action:@selector(changeRangingState:) forControlEvents:UIControlEventValueChanged];
296 |
297 | }
298 |
299 | - (void)didReceiveMemoryWarning
300 | {
301 | [super didReceiveMemoryWarning];
302 | // Dispose of any resources that can be recreated.
303 | }
304 |
305 | @end
306 |
--------------------------------------------------------------------------------
/client-iphone/piBeacon-iphone/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/client-iphone/piBeacon-iphone/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // piBeacon-iphone
4 | //
5 | // Created by Matt Schmulen on 12/24/13.
6 | // Copyright (c) 2013 Matt Schmulen. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | #import "AppDelegate.h"
12 |
13 | int main(int argc, char * argv[])
14 | {
15 | @autoreleasepool {
16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/client-iphone/piBeacon-iphone/piBeacon-iphone-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | ${PRODUCT_NAME}
9 | CFBundleExecutable
10 | ${EXECUTABLE_NAME}
11 | CFBundleIdentifier
12 | com.mattschmulen.${PRODUCT_NAME:rfc1034identifier}
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | ${PRODUCT_NAME}
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | 1.0
25 | LSRequiresIPhoneOS
26 |
27 | UIBackgroundModes
28 |
29 | bluetooth-peripheral
30 |
31 | UIMainStoryboardFile
32 | Main
33 | UIRequiredDeviceCapabilities
34 |
35 | armv7
36 |
37 | UIStatusBarTintParameters
38 |
39 | UINavigationBar
40 |
41 | Style
42 | UIBarStyleDefault
43 | Translucent
44 |
45 |
46 |
47 | UISupportedInterfaceOrientations
48 |
49 | UIInterfaceOrientationPortrait
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/client-iphone/piBeacon-iphone/piBeacon-iphone-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // Prefix header
3 | //
4 | // The contents of this file are implicitly included at the beginning of every source file.
5 | //
6 |
7 | #import
8 |
9 | #ifndef __IPHONE_5_0
10 | #warning "This project uses features only available in iOS SDK 5.0 and later."
11 | #endif
12 |
13 | #ifdef __OBJC__
14 | #import
15 | #import
16 | #endif
17 |
--------------------------------------------------------------------------------
/client-iphone/piBeacon-iphone/piBeacon/ModelEngagement.h:
--------------------------------------------------------------------------------
1 | //
2 | // ModelEngagement.h
3 | // herald
4 | //
5 | // Created by Matt Schmulen on 10/28/13.
6 | // Copyright (c) 2013 Matt Schmulen. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | typedef NS_ENUM(NSInteger, BLE_TYPE) { BLE_TYPE_IBEACON, BLE_TYPE_UNKNOWN };
12 |
13 | @interface ModelEngagement : NSObject
14 |
15 | @property(nonatomic) NSDate *startTime;
16 | @property(nonatomic) NSDate *endTime;
17 |
18 | @property(nonatomic) NSString *iBeaconProximityUUID;
19 | @property(nonatomic) NSString *iBeaconRegionIdentifier;
20 |
21 | @property(nonatomic) NSNumber *iBeaconProximityMajor;
22 | @property(nonatomic) NSNumber *iBeaconProximityMinor;
23 |
24 | @property(nonatomic) BLE_TYPE bleType;
25 |
26 | //arc4random()
27 | //http://stackoverflow.com/questions/7363840/using-a-unique-identifier-of-iphone-or-ios-device
28 | //CFUUIDRef theUUID = CFUUIDCreate(NULL);
29 | @property(nonatomic) CFUUIDRef engagementID;
30 |
31 | @end
32 |
--------------------------------------------------------------------------------
/client-iphone/piBeacon-iphone/piBeacon/ModelEngagement.m:
--------------------------------------------------------------------------------
1 | //
2 | // ModelEngagement.m
3 | // herald
4 | //
5 | // Created by Matt Schmulen on 10/28/13.
6 | // Copyright (c) 2013 Matt Schmulen. All rights reserved.
7 | //
8 |
9 | #import "ModelEngagement.h"
10 |
11 |
12 | @implementation ModelEngagement
13 |
14 | @synthesize engagementID;
15 |
16 | - (id)init {
17 | if(self = [super init]) {
18 | self.engagementID = CFUUIDCreate(NULL);
19 | }
20 |
21 | return self;
22 | }
23 |
24 | @end
25 |
--------------------------------------------------------------------------------
/client-iphone/piBeacon-iphone/piBeacon/piBeacon.h:
--------------------------------------------------------------------------------
1 | //
2 | // piBeacon.h
3 | // piBeacon-iphone
4 | //
5 | // Created by Matt Schmulen on 12/26/13.
6 | // Copyright (c) 2013 Matt Schmulen. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "ModelEngagement.h"
11 | #import "piBeaconDetailViewController.h"
12 | #import "piBeaconProximityAlertViewController.h"
13 |
14 |
15 | //Notifications
16 | static NSString * const notification_NewEngagement = @"NewEngagementNotification";
17 | //static NSString * const notification_NewEngagement = @"NewEngagementNotification";
18 | //static NSString * const notification_NewEngagement = @"NewEngagementNotification";
19 |
20 | @interface piBeacon : NSObject
21 |
22 | -(void) initWithConfig:(NSString *)beaconUUID beaconRegionId:(NSString*) beaconRegionId beaconMajor:(NSInteger)beaconMajor beaconMinor:(NSInteger)beaconMinor;
23 |
24 | //Beacon config
25 | @property(nonatomic) NSInteger piMajor;
26 | @property(nonatomic) NSInteger piMinor;
27 | @property(nonatomic) NSString *piUUID;
28 | @property(nonatomic) NSString *piRegionIdentifier;
29 |
30 | @property(nonatomic,retain) NSString *strUserName;
31 | @property(nonatomic,retain) NSString *strUserTitle;
32 |
33 | + (void) simulateProximityEvent;
34 |
35 | @end
36 |
--------------------------------------------------------------------------------
/client-iphone/piBeacon-iphone/piBeacon/piBeacon.m:
--------------------------------------------------------------------------------
1 | //
2 | // piBeacon.m
3 | // piBeacon-iphone
4 | //
5 | // Created by Matt Schmulen on 12/26/13.
6 | // Copyright (c) 2013 Matt Schmulen. All rights reserved.
7 | //
8 |
9 | #import "piBeacon.h"
10 |
11 |
12 | @interface piBeacon ()
13 |
14 | @property (nonatomic, assign) NSUserDefaults * userDefaults;
15 |
16 | @end
17 |
18 | @implementation piBeacon
19 |
20 | @synthesize piMajor,piMinor,piUUID,strUserName,strUserTitle;
21 |
22 | -(void) initWithConfig:(NSString *)beaconUUID beaconRegionId:(NSString*) beaconRegionId beaconMajor:(NSInteger)beaconMajor beaconMinor:(NSInteger)beaconMinor;
23 | {
24 | //[NSUserDefaults resetStandardUserDefaults];
25 | //self.userDefaults = [NSUserDefaults standardUserDefaults];
26 |
27 | //create NSUserDefault keys
28 | time_t t;
29 | srand((unsigned) time(&t)); //seed the rand with the time
30 |
31 | int randomMinor = rand() % 65535;
32 |
33 | self.piMajor = beaconMajor; // piBeacon convention is iOS devices are Major = 2;//major;
34 | self.piMinor = randomMinor;
35 | self.piUUID = beaconUUID;
36 | self.piRegionIdentifier = beaconRegionId;
37 |
38 | self.strUserName = @"King Harald Bluetooth";
39 | self.strUserTitle = @"The Last Viking";
40 |
41 | NSLog(@"piBeacon region: %@ ", self.piRegionIdentifier);
42 | NSLog(@"piBeacon uuid:%@", self.piUUID );
43 | NSLog(@"major: %ld minor: %ld ", (long)self.piMajor, (long)self.piMinor );
44 |
45 | /*
46 | if(self.userDefaults)
47 | {
48 | if([[NSUserDefaults standardUserDefaults] objectForKey:@"strUserName"] == nil) {
49 |
50 | //create NSUserDefault keys
51 | time_t t;
52 | srand((unsigned) time(&t)); //seed the rand with the time
53 |
54 | self.piMajor = rand();
55 | self.piMinor = rand();
56 |
57 | //Set
58 | [self.userDefaults setInteger: self.piMajor forKey:@"piBeaconProximityMajor"];
59 | [self.userDefaults setInteger: self.piMinor forKey:@"piBeaconProximityMinor"];
60 | [self.userDefaults setObject: self.piUUID forKey:@"piBeaconUUID"];
61 |
62 | //user defaults
63 | [self.userDefaults setObject: @"King Harald Bluetooth" forKey:@"strUserName"];
64 | [self.userDefaults setObject: @"The Last Viking" forKey:@"strUserTitle"];
65 |
66 | //Sync the userDefatuls
67 | //[self.userDefaults synchronize];
68 | }
69 |
70 | //Retrieve
71 | self.piMajor = [self.userDefaults integerForKey:@"piBeaconProximityMajor"];
72 | self.piMinor = [self.userDefaults integerForKey:@"piBeaconProximityMinor"];
73 | self.piUUID = [self.userDefaults stringForKey:@"piBeaconUUID"];
74 |
75 | self.strUserName = [self.userDefaults stringForKey:@"strUserName"];
76 | self.strUserTitle = [self.userDefaults stringForKey:@"strUserTitle"];
77 | }
78 | else {
79 | NSLog(@"applicationDidFinishLaunching: Error reading config file.");
80 | }
81 | */
82 |
83 | }
84 |
85 |
86 | #pragma mark - Engagment
87 | - (ModelEngagement *) engagementFactory: (NSString*) beaconProximityUUID
88 | {
89 | ModelEngagement *engagement = [[ModelEngagement alloc] init];
90 |
91 | engagement.startTime = [[NSDate alloc] init];
92 | engagement.endTime = [[NSDate alloc] init];
93 |
94 | engagement.iBeaconProximityUUID = beaconProximityUUID;
95 | engagement.iBeaconRegionIdentifier = self.piRegionIdentifier;
96 | engagement.bleType = BLE_TYPE_IBEACON;
97 |
98 | //[[NSNotificationCenter defaultCenter] postNotificationName:notification_NewEngagement object:engagement];
99 |
100 | return engagement;
101 | }//end engagementFactory
102 |
103 | - (void) startEngagement
104 | {
105 | //[self.engagementFactory
106 | //ModelEngagement *engagement = [self engagementFactory:self.piBeacon.piUUID];
107 | //engagement.iBeaconRegionIdentifier = region.identifier;
108 |
109 | //engagement.iBeaconProximityMajor = region.major;
110 | //engagement.iBeaconProximityMinor = region.minor;
111 | //engagement.bleType =
112 |
113 | }
114 |
115 | - (void) endEngagement
116 | {
117 |
118 | }
119 |
120 | + (void) simulateProximityEvent
121 | {
122 | NSLog(@"Simulate Proximity Event");
123 |
124 | [[NSNotificationCenter defaultCenter] postNotificationName:notification_NewEngagement object:nil];
125 | }
126 |
127 |
128 |
129 | @end
130 |
--------------------------------------------------------------------------------
/client-iphone/piBeacon-iphone/piBeacon/piBeaconDetailViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // piBeaconDetailViewController.h
3 | // piBeacon-iphone
4 | //
5 | // Created by Matt Schmulen on 12/26/13.
6 | // Copyright (c) 2013 Matt Schmulen. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface piBeaconDetailViewController : UIViewController
12 |
13 | @property NSObject *model;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/client-iphone/piBeacon-iphone/piBeacon/piBeaconDetailViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // piBeaconDetailViewController.m
3 | // piBeacon-iphone
4 | //
5 | // Created by Matt Schmulen on 12/26/13.
6 | // Copyright (c) 2013 Matt Schmulen. All rights reserved.
7 | //
8 |
9 | #import "piBeaconDetailViewController.h"
10 |
11 | @interface piBeaconDetailViewController ()
12 |
13 | @end
14 |
15 | @implementation piBeaconDetailViewController
16 |
17 | @synthesize model;
18 |
19 | - (IBAction)actionClose:(id)sender {
20 | [self dismissViewControllerAnimated:YES completion:nil];
21 | }
22 |
23 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
24 | {
25 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
26 | //self = [[NSBundle mainBundle] loadNibNamed:@"piBeaconDetailViewController" owner:self options:nil][0]
27 | if (self) {
28 | // Custom initialization
29 | }
30 | return self;
31 | }
32 |
33 | - (void)viewDidLoad
34 | {
35 | [super viewDidLoad];
36 | // Do any additional setup after loading the view from its nib.
37 | }
38 |
39 | - (void)didReceiveMemoryWarning
40 | {
41 | [super didReceiveMemoryWarning];
42 | // Dispose of any resources that can be recreated.
43 | }
44 |
45 | @end
46 |
--------------------------------------------------------------------------------
/client-iphone/piBeacon-iphone/piBeacon/piBeaconDetailViewController.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
23 |
29 |
35 |
41 |
47 |
53 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
--------------------------------------------------------------------------------
/client-iphone/piBeacon-iphone/piBeacon/piBeaconProximityAlertViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // piBeaconProximityAlertViewController.h
3 | // piBeacon-iphone
4 | //
5 | // Created by Matt Schmulen on 12/29/13.
6 | // Copyright (c) 2013 Matt Schmulen. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface piBeaconProximityAlertViewController : UIViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/client-iphone/piBeacon-iphone/piBeacon/piBeaconProximityAlertViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // piBeaconProximityAlertViewController.m
3 | // piBeacon-iphone
4 | //
5 | // Created by Matt Schmulen on 12/29/13.
6 | // Copyright (c) 2013 Matt Schmulen. All rights reserved.
7 | //
8 |
9 | #import "piBeaconProximityAlertViewController.h"
10 |
11 | @interface piBeaconProximityAlertViewController ()
12 |
13 | @end
14 |
15 | @implementation piBeaconProximityAlertViewController
16 | - (IBAction)actionClose:(id)sender {
17 | [self dismissViewControllerAnimated:YES completion:nil];
18 | }
19 |
20 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
21 | {
22 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
23 | if (self) {
24 | // Custom initialization
25 | }
26 | return self;
27 | }
28 |
29 | - (void)viewDidLoad
30 | {
31 | [super viewDidLoad];
32 | // Do any additional setup after loading the view from its nib.
33 | }
34 |
35 | - (void)didReceiveMemoryWarning
36 | {
37 | [super didReceiveMemoryWarning];
38 | // Dispose of any resources that can be recreated.
39 | }
40 |
41 | @end
42 |
--------------------------------------------------------------------------------
/client-iphone/piBeacon-iphone/piBeacon/piBeaconProximityAlertViewController.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
24 |
31 |
32 |
33 |
34 |
35 |
43 |
50 |
57 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
--------------------------------------------------------------------------------
/client-iphone/piBeacon-iphone/piBeacon/piBeaconUserDetailViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // piBeaconUserDetailViewController.h
3 | // piBeacon-iphone
4 | //
5 | // Created by Matt Schmulen on 12/26/13.
6 | // Copyright (c) 2013 Matt Schmulen. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface piBeaconUserDetailViewController : UIViewController
12 | @property NSObject *model;
13 | @end
14 |
--------------------------------------------------------------------------------
/client-iphone/piBeacon-iphone/piBeacon/piBeaconUserDetailViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // piBeaconUserDetailViewController.m
3 | // piBeacon-iphone
4 | //
5 | // Created by Matt Schmulen on 12/26/13.
6 | // Copyright (c) 2013 Matt Schmulen. All rights reserved.
7 | //
8 |
9 | #import "piBeaconUserDetailViewController.h"
10 |
11 | @interface piBeaconUserDetailViewController ()
12 |
13 | @end
14 |
15 | @implementation piBeaconUserDetailViewController
16 |
17 | @synthesize model;
18 |
19 |
20 | - (IBAction)actionClose:(id)sender {
21 |
22 | [self dismissViewControllerAnimated:YES completion:nil];
23 | }
24 |
25 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
26 | {
27 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
28 | if (self) {
29 | // Custom initialization
30 | }
31 | return self;
32 | }
33 |
34 | - (void)viewDidLoad
35 | {
36 | [super viewDidLoad];
37 | // Do any additional setup after loading the view from its nib.
38 | }
39 |
40 | - (void)didReceiveMemoryWarning
41 | {
42 | [super didReceiveMemoryWarning];
43 | // Dispose of any resources that can be recreated.
44 | }
45 |
46 | @end
47 |
--------------------------------------------------------------------------------
/client-iphone/piBeacon-iphone/piBeacon/piBeaconUserDetailViewController.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
55 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
--------------------------------------------------------------------------------
/client-iphone/piBeacon-iphoneTests/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/client-iphone/piBeacon-iphoneTests/piBeacon-iphoneTests-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | com.mattschmulen.${PRODUCT_NAME:rfc1034identifier}
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundlePackageType
14 | BNDL
15 | CFBundleShortVersionString
16 | 1.0
17 | CFBundleSignature
18 | ????
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/client-iphone/piBeacon-iphoneTests/piBeacon_iphoneTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // piBeacon_iphoneTests.m
3 | // piBeacon-iphoneTests
4 | //
5 | // Created by Matt Schmulen on 12/24/13.
6 | // Copyright (c) 2013 Matt Schmulen. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface piBeacon_iphoneTests : XCTestCase
12 |
13 | @end
14 |
15 | @implementation piBeacon_iphoneTests
16 |
17 | - (void)setUp
18 | {
19 | [super setUp];
20 | // Put setup code here. This method is called before the invocation of each test method in the class.
21 | }
22 |
23 | - (void)tearDown
24 | {
25 | // Put teardown code here. This method is called after the invocation of each test method in the class.
26 | [super tearDown];
27 | }
28 |
29 | - (void)testExample
30 | {
31 | XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__);
32 | }
33 |
34 | @end
35 |
--------------------------------------------------------------------------------
/ibeacon-node-collector/app.js:
--------------------------------------------------------------------------------
1 | var loopback = require('loopback');
2 | var path = require('path');
3 | var app = module.exports = loopback();
4 | var started = new Date();
5 |
6 | /*
7 | * 1. Configure LoopBack models and datasources
8 | *
9 | * Read more at http://apidocs.strongloop.com/loopback#appbootoptions
10 | */
11 |
12 | app.boot(__dirname);
13 |
14 | /*
15 | * 2. Configure request preprocessing
16 | *
17 | * LoopBack support all express-compatible middleware.
18 | */
19 |
20 | app.use(loopback.favicon());
21 | app.use(loopback.logger(app.get('env') === 'development' ? 'dev' : 'default'));
22 | app.use(loopback.cookieParser(app.get('cookieSecret')));
23 | app.use(loopback.token({model: app.models.accessToken}));
24 | app.use(loopback.bodyParser());
25 | app.use(loopback.methodOverride());
26 |
27 | /*
28 | * EXTENSION POINT
29 | * Add your custom request-preprocessing middleware here.
30 | * Example:
31 | * app.use(loopback.limit('5.5mb'))
32 | */
33 |
34 | /*
35 | * 3. Setup request handlers.
36 | */
37 |
38 | // LoopBack REST interface
39 | app.use(app.get('restApiRoot'), loopback.rest());
40 |
41 | // API explorer (if present)
42 | try {
43 | var explorer = require('loopback-explorer')(app);
44 | app.use('/explorer', explorer);
45 | app.once('started', function(baseUrl) {
46 | console.log('Browse your REST API at %s%s', baseUrl, explorer.route);
47 | });
48 | } catch(e){
49 | console.log(
50 | 'Run `npm install loopback-explorer` to enable the LoopBack explorer'
51 | );
52 | }
53 |
54 | /*
55 | * EXTENSION POINT
56 | * Add your custom request-handling middleware here.
57 | * Example:
58 | * app.use(function(req, resp, next) {
59 | * if (req.url == '/status') {
60 | * // send status response
61 | * } else {
62 | * next();
63 | * }
64 | * });
65 | */
66 |
67 | // Let express routes handle requests that were not handled
68 | // by any of the middleware registered above.
69 | // This way LoopBack REST and API Explorer take precedence over
70 | // express routes.
71 | app.use(app.router);
72 |
73 | // The static file server should come after all other routes
74 | // Every request that goes through the static middleware hits
75 | // the file system to check if a file exists.
76 | app.use(loopback.static(path.join(__dirname, 'public')));
77 |
78 | // Requests that get this far won't be handled
79 | // by any middleware. Convert them into a 404 error
80 | // that will be handled later down the chain.
81 | app.use(loopback.urlNotFound());
82 |
83 | /*
84 | * 4. Setup error handling strategy
85 | */
86 |
87 | /*
88 | * EXTENSION POINT
89 | * Add your custom error reporting middleware here
90 | * Example:
91 | * app.use(function(err, req, resp, next) {
92 | * console.log(req.url, ' failed: ', err.stack);
93 | * next(err);
94 | * });
95 | */
96 |
97 | // The ultimate error handler.
98 | app.use(loopback.errorHandler());
99 |
100 |
101 | /*
102 | * 5. Add a basic application status route at the root `/`.
103 | *
104 | * (remove this to handle `/` on your own)
105 | */
106 |
107 | app.get('/', loopback.status());
108 |
109 | /*
110 | * 6. Enable access control and token based authentication.
111 | */
112 |
113 | var swaggerRemote = app.remotes().exports.swagger;
114 | if (swaggerRemote) swaggerRemote.requireToken = false;
115 |
116 | app.enableAuth();
117 |
118 | /*
119 | * 7. Optionally start the server
120 | *
121 | * (only if this module is the main module)
122 | */
123 |
124 | app.start = function() {
125 | return app.listen(function() {
126 | var baseUrl = 'http://' + app.get('host') + ':' + app.get('port');
127 | app.emit('started', baseUrl);
128 | console.log('LoopBack server listening @ %s%s', baseUrl, '/');
129 | });
130 | };
131 |
132 | if(require.main === module) {
133 | app.start();
134 | }
135 |
--------------------------------------------------------------------------------
/ibeacon-node-collector/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "port": 3000,
3 | "host": "0.0.0.0",
4 | "cookieSecret": "993a5e14-783a-41de-9224-e7f72e014419"
5 | }
6 |
--------------------------------------------------------------------------------
/ibeacon-node-collector/boot/init.js:
--------------------------------------------------------------------------------
1 |
2 | var loopback = require('loopback');
3 | var app = require('../app');
4 |
5 | var ibeacon = app.models.ibeacon;
6 | var Bleacon = require('bleacon');
7 | var ibeaconCache = new Array();
8 |
9 | Bleacon.on('discover', function(bleacon) {
10 | //console.log( bleacon );
11 |
12 | var dbID = 0;
13 | var guid = bleacon.uuid + bleacon.major + bleacon.minor;
14 | if ( guid in ibeaconCache ) { dbID = ibeaconCache[guid]; }
15 |
16 | ibeacon.upsert(
17 | { id: dbID , guid:guid, uuid:bleacon.uuid, major:bleacon.major, minor:bleacon.minor},
18 | function( error, _ibeacon)
19 | {
20 | ibeaconCache[guid] = _ibeacon.id;
21 | if ( error ) { console.log( "error on upsert " ); }
22 | else {
23 | //console.log( "upsert - :" + _ibeacon.id + " guid " + _ibeacon.guid );
24 | var eng = app.models.engagement;
25 | eng.create({ pBeaconID: _ibeacon.id, timestamp: Date.now(), rssi: bleacon.rssi, proximity: bleacon.proximity });
26 | } //end else success
27 | }); //end upser
28 |
29 | var signal = [bleacon.rssi/5];
30 | var xs = new Array(Math.floor(-bleacon.rssi/2) + 1).join('x');
31 | console.log("rssi:" +xs);
32 |
33 | });//end on discover
34 |
35 | Bleacon.startScanning();
36 |
--------------------------------------------------------------------------------
/ibeacon-node-collector/datasources.json:
--------------------------------------------------------------------------------
1 | {
2 | "db": {
3 | "defaultForType": "db",
4 | "connector": "memory"
5 | },
6 | "push": {
7 | "defaultForType": "push",
8 | "connector": "loopback-push-notification",
9 | "installation": "installation",
10 | "notification": "notification",
11 | "application": "application"
12 | },
13 | "mail": {
14 | "defaultForType": "mail",
15 | "connector": "mail"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/ibeacon-node-collector/models.json:
--------------------------------------------------------------------------------
1 | {
2 | "email": {
3 | "options": {
4 | "base": "Email"
5 | },
6 | "dataSource": "mail",
7 | "public": false
8 | },
9 | "user": {
10 | "options": {
11 | "base": "User",
12 | "relations": {
13 | "accessTokens": {
14 | "model": "accessToken",
15 | "type": "hasMany",
16 | "foreignKey": "userId"
17 | }
18 | }
19 | },
20 | "dataSource": "db",
21 | "public": true
22 | },
23 | "accessToken": {
24 | "options": {
25 | "base": "AccessToken"
26 | },
27 | "dataSource": "db",
28 | "public": true
29 | },
30 | "application": {
31 | "options": {
32 | "base": "Application"
33 | },
34 | "dataSource": "db",
35 | "public": true
36 | },
37 | "acl": {
38 | "options": {
39 | "base": "ACL"
40 | },
41 | "dataSource": "db",
42 | "public": false
43 | },
44 | "roleMapping": {
45 | "options": {
46 | "base": "RoleMapping"
47 | },
48 | "dataSource": "db",
49 | "public": false
50 | },
51 | "role": {
52 | "options": {
53 | "base": "Role",
54 | "relations": {
55 | "principals": {
56 | "type": "hasMany",
57 | "model": "roleMapping",
58 | "foreignKey": "roleId"
59 | }
60 | }
61 | },
62 | "dataSource": "db",
63 | "public": false
64 | },
65 | "scope": {
66 | "options": {
67 | "base": "Scope"
68 | },
69 | "dataSource": "db",
70 | "public": false
71 | },
72 | "push": {
73 | "options": {
74 | "base": "Push",
75 | "plural": "push"
76 | },
77 | "dataSource": "push"
78 | },
79 | "installation": {
80 | "options": {
81 | "base": "Installation"
82 | },
83 | "dataSource": "db",
84 | "public": true
85 | },
86 | "notification": {
87 | "options": {
88 | "base": "Notification"
89 | },
90 | "dataSource": "db",
91 | "public": true
92 | },
93 | "ibeacon": {
94 | "properties": {},
95 | "public": true,
96 | "dataSource": "db"
97 | },
98 | "engagement": {
99 | "properties": {},
100 | "public": true,
101 | "dataSource": "db"
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/ibeacon-node-collector/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "0.0.0",
3 | "main": "app.js",
4 | "bin": "server.js",
5 | "scripts": {
6 | "start": "node app.js"
7 | },
8 | "dependencies": {
9 | "loopback": "1.5.x",
10 | "bleacon": "~0.2.0"
11 | },
12 | "optionalDependencies": {
13 | "loopback-explorer": "~1.1.0",
14 | "loopback-push-notification": "~1.1.0"
15 | },
16 | "name": "ibeacon-node-collector"
17 | }
18 |
--------------------------------------------------------------------------------
/screenshots/api-ibeacons.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mschmulen/tracking-bluetooth-ibeacons-with-node/2798b01ac4af5ff7ad8a46019ea8ea1b8178d6a2/screenshots/api-ibeacons.png
--------------------------------------------------------------------------------
/screenshots/ble-analytics.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mschmulen/tracking-bluetooth-ibeacons-with-node/2798b01ac4af5ff7ad8a46019ea8ea1b8178d6a2/screenshots/ble-analytics.png
--------------------------------------------------------------------------------
/screenshots/ble-apps-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mschmulen/tracking-bluetooth-ibeacons-with-node/2798b01ac4af5ff7ad8a46019ea8ea1b8178d6a2/screenshots/ble-apps-2.png
--------------------------------------------------------------------------------
/screenshots/ble-apps.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mschmulen/tracking-bluetooth-ibeacons-with-node/2798b01ac4af5ff7ad8a46019ea8ea1b8178d6a2/screenshots/ble-apps.png
--------------------------------------------------------------------------------
/screenshots/ble-mobile-multi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mschmulen/tracking-bluetooth-ibeacons-with-node/2798b01ac4af5ff7ad8a46019ea8ea1b8178d6a2/screenshots/ble-mobile-multi.png
--------------------------------------------------------------------------------
/screenshots/ble-mobile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mschmulen/tracking-bluetooth-ibeacons-with-node/2798b01ac4af5ff7ad8a46019ea8ea1b8178d6a2/screenshots/ble-mobile.png
--------------------------------------------------------------------------------
/screenshots/ble-ranging.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mschmulen/tracking-bluetooth-ibeacons-with-node/2798b01ac4af5ff7ad8a46019ea8ea1b8178d6a2/screenshots/ble-ranging.png
--------------------------------------------------------------------------------
/screenshots/console-run.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mschmulen/tracking-bluetooth-ibeacons-with-node/2798b01ac4af5ff7ad8a46019ea8ea1b8178d6a2/screenshots/console-run.png
--------------------------------------------------------------------------------
/screenshots/estimote-ibeacon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mschmulen/tracking-bluetooth-ibeacons-with-node/2798b01ac4af5ff7ad8a46019ea8ea1b8178d6a2/screenshots/estimote-ibeacon.png
--------------------------------------------------------------------------------
/screenshots/explorer-ibeacons.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mschmulen/tracking-bluetooth-ibeacons-with-node/2798b01ac4af5ff7ad8a46019ea8ea1b8178d6a2/screenshots/explorer-ibeacons.png
--------------------------------------------------------------------------------
/screenshots/image1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mschmulen/tracking-bluetooth-ibeacons-with-node/2798b01ac4af5ff7ad8a46019ea8ea1b8178d6a2/screenshots/image1.png
--------------------------------------------------------------------------------
/screenshots/image2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mschmulen/tracking-bluetooth-ibeacons-with-node/2798b01ac4af5ff7ad8a46019ea8ea1b8178d6a2/screenshots/image2.png
--------------------------------------------------------------------------------
/screenshots/loopback-explorer-beacon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mschmulen/tracking-bluetooth-ibeacons-with-node/2798b01ac4af5ff7ad8a46019ea8ea1b8178d6a2/screenshots/loopback-explorer-beacon.png
--------------------------------------------------------------------------------
/screenshots/loopback-explorer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mschmulen/tracking-bluetooth-ibeacons-with-node/2798b01ac4af5ff7ad8a46019ea8ea1b8178d6a2/screenshots/loopback-explorer.png
--------------------------------------------------------------------------------
/screenshots/loopback-filter-near.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mschmulen/tracking-bluetooth-ibeacons-with-node/2798b01ac4af5ff7ad8a46019ea8ea1b8178d6a2/screenshots/loopback-filter-near.png
--------------------------------------------------------------------------------