├── .gitignore ├── AprilBeaconDemo ├── AprilBeaconDemo.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ └── AprilBeaconDemo.xccheckout ├── AprilBeaconDemo │ ├── ABAppDelegate.h │ ├── ABAppDelegate.m │ ├── ABBeaconViewController.h │ ├── ABBeaconViewController.m │ ├── ABBluetoothViewController.h │ ├── ABBluetoothViewController.m │ ├── ABModifyViewController.h │ ├── ABModifyViewController.m │ ├── ABNotificationViewController.h │ ├── ABNotificationViewController.m │ ├── ABSelectDeviceViewController.h │ ├── ABSelectDeviceViewController.m │ ├── ABSensorListViewController.h │ ├── ABSensorListViewController.m │ ├── ABSensorViewController.h │ ├── ABSensorViewController.m │ ├── ABTransmitters.h │ ├── ABTransmitters.m │ ├── ABUUIDTextField.h │ ├── ABUUIDTextField.m │ ├── AprilBeaconDemo-Info.plist │ ├── AprilBeaconDemo-Prefix.pch │ ├── Base.lproj │ │ └── Main.storyboard │ ├── Images.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── LaunchImage.launchimage │ │ │ └── Contents.json │ ├── LaunchScreen.xib │ ├── en.lproj │ │ └── InfoPlist.strings │ └── main.m ├── AprilBeaconDemoTests │ ├── AprilBeaconDemoTests-Info.plist │ ├── AprilBeaconDemoTests.m │ └── en.lproj │ │ └── InfoPlist.strings ├── JVFloatLabeledTextField │ ├── JVFloatLabeledTextField.h │ ├── JVFloatLabeledTextField.m │ ├── JVFloatLabeledTextView.h │ ├── JVFloatLabeledTextView.m │ ├── NSString+TextDirectionality.h │ └── NSString+TextDirectionality.m └── tile_floor.png ├── AprilSDK.podspec ├── AprilSDK ├── Headers │ ├── ABBeacon.h │ ├── ABBeaconManager.h │ ├── ABBeaconRegion.h │ ├── ABBluetoothManager.h │ ├── ABDefinitions.h │ ├── ABError.h │ ├── ABSensor.h │ └── AprilBeaconSDK.h └── libAprilBeaconSDK.a ├── CHANGELOG.md ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | _Store 2 | build/ 3 | *.pbxuser 4 | !default.pbxuser 5 | *.mode1v3 6 | !default.mode1v3 7 | *.mode2v3 8 | !default.mode2v3 9 | *.perspectivev3 10 | !default.perspectivev3 11 | xcuserdata 12 | profile 13 | *.moved-aside 14 | DerivedData 15 | .idea/ 16 | -------------------------------------------------------------------------------- /AprilBeaconDemo/AprilBeaconDemo.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | E23E40781BD5DC2B00B17F49 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = E23E40771BD5DC2B00B17F49 /* LaunchScreen.xib */; }; 11 | E254A8D419E7B4DE007BBE3C /* libAprilBeaconSDK.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E254A8D319E7B4DE007BBE3C /* libAprilBeaconSDK.a */; }; 12 | E26EB6AC197F5323007619B1 /* ABModifyViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = E26EB6AB197F5323007619B1 /* ABModifyViewController.m */; }; 13 | E26EB6B4197F5374007619B1 /* JVFloatLabeledTextField.m in Sources */ = {isa = PBXBuildFile; fileRef = E26EB6AF197F5374007619B1 /* JVFloatLabeledTextField.m */; }; 14 | E26EB6B5197F5374007619B1 /* JVFloatLabeledTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = E26EB6B1197F5374007619B1 /* JVFloatLabeledTextView.m */; }; 15 | E26EB6B6197F5374007619B1 /* NSString+TextDirectionality.m in Sources */ = {isa = PBXBuildFile; fileRef = E26EB6B3197F5374007619B1 /* NSString+TextDirectionality.m */; }; 16 | E2D134981ABA973400A7A3BF /* ABTransmitters.m in Sources */ = {isa = PBXBuildFile; fileRef = E2D134951ABA973400A7A3BF /* ABTransmitters.m */; }; 17 | E2D134991ABA973400A7A3BF /* ABUUIDTextField.m in Sources */ = {isa = PBXBuildFile; fileRef = E2D134971ABA973400A7A3BF /* ABUUIDTextField.m */; }; 18 | E2ED5E551919E1F000C0BF2C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E2ED5E541919E1F000C0BF2C /* Foundation.framework */; }; 19 | E2ED5E571919E1F000C0BF2C /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E2ED5E561919E1F000C0BF2C /* CoreGraphics.framework */; }; 20 | E2ED5E591919E1F000C0BF2C /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E2ED5E581919E1F000C0BF2C /* UIKit.framework */; }; 21 | E2ED5E5F1919E1F000C0BF2C /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = E2ED5E5D1919E1F000C0BF2C /* InfoPlist.strings */; }; 22 | E2ED5E611919E1F000C0BF2C /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = E2ED5E601919E1F000C0BF2C /* main.m */; }; 23 | E2ED5E651919E1F000C0BF2C /* ABAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = E2ED5E641919E1F000C0BF2C /* ABAppDelegate.m */; }; 24 | E2ED5E681919E1F000C0BF2C /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E2ED5E661919E1F000C0BF2C /* Main.storyboard */; }; 25 | E2ED5E6B1919E1F000C0BF2C /* ABBeaconViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = E2ED5E6A1919E1F000C0BF2C /* ABBeaconViewController.m */; }; 26 | E2ED5E6D1919E1F000C0BF2C /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E2ED5E6C1919E1F000C0BF2C /* Images.xcassets */; }; 27 | E2ED5E741919E1F000C0BF2C /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E2ED5E731919E1F000C0BF2C /* XCTest.framework */; }; 28 | E2ED5E751919E1F100C0BF2C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E2ED5E541919E1F000C0BF2C /* Foundation.framework */; }; 29 | E2ED5E761919E1F100C0BF2C /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E2ED5E581919E1F000C0BF2C /* UIKit.framework */; }; 30 | E2ED5E7E1919E1F100C0BF2C /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = E2ED5E7C1919E1F100C0BF2C /* InfoPlist.strings */; }; 31 | E2ED5E801919E1F100C0BF2C /* AprilBeaconDemoTests.m in Sources */ = {isa = PBXBuildFile; fileRef = E2ED5E7F1919E1F100C0BF2C /* AprilBeaconDemoTests.m */; }; 32 | E2ED5EE5191B32C600C0BF2C /* ABBluetoothViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = E2ED5EDD191B32C600C0BF2C /* ABBluetoothViewController.m */; }; 33 | E2ED5EE6191B32C600C0BF2C /* ABNotificationViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = E2ED5EDF191B32C600C0BF2C /* ABNotificationViewController.m */; }; 34 | E2ED5EE7191B32C600C0BF2C /* ABSelectDeviceViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = E2ED5EE1191B32C600C0BF2C /* ABSelectDeviceViewController.m */; }; 35 | E2FB5642199DA9780038CAA8 /* ABSensorViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = E2FB5640199DA9780038CAA8 /* ABSensorViewController.m */; }; 36 | E2FB5645199DA9A70038CAA8 /* ABSensorListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = E2FB5644199DA9A70038CAA8 /* ABSensorListViewController.m */; }; 37 | E2FB5647199DAC2E0038CAA8 /* tile_floor.png in Resources */ = {isa = PBXBuildFile; fileRef = E2FB5646199DAC2E0038CAA8 /* tile_floor.png */; }; 38 | /* End PBXBuildFile section */ 39 | 40 | /* Begin PBXContainerItemProxy section */ 41 | E2ED5E771919E1F100C0BF2C /* PBXContainerItemProxy */ = { 42 | isa = PBXContainerItemProxy; 43 | containerPortal = E2ED5E491919E1F000C0BF2C /* Project object */; 44 | proxyType = 1; 45 | remoteGlobalIDString = E2ED5E501919E1F000C0BF2C; 46 | remoteInfo = AprilBeaconDemo; 47 | }; 48 | /* End PBXContainerItemProxy section */ 49 | 50 | /* Begin PBXFileReference section */ 51 | 3EC0A1A11C3F659700945F45 /* ABBeaconManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ABBeaconManager.h; sourceTree = ""; }; 52 | 48A91E451AE78822007A1B43 /* ABError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ABError.h; sourceTree = ""; }; 53 | E23E40771BD5DC2B00B17F49 /* LaunchScreen.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = LaunchScreen.xib; sourceTree = ""; }; 54 | E23E40791BD5DF2B00B17F49 /* ABBluetoothManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ABBluetoothManager.h; sourceTree = ""; }; 55 | E23E407A1BD5DF2B00B17F49 /* ABDefinitions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ABDefinitions.h; sourceTree = ""; }; 56 | E254A8CE19E7B4DE007BBE3C /* ABBeacon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ABBeacon.h; sourceTree = ""; }; 57 | E254A8D019E7B4DE007BBE3C /* ABBeaconRegion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ABBeaconRegion.h; sourceTree = ""; }; 58 | E254A8D119E7B4DE007BBE3C /* ABSensor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ABSensor.h; sourceTree = ""; }; 59 | E254A8D219E7B4DE007BBE3C /* AprilBeaconSDK.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AprilBeaconSDK.h; sourceTree = ""; }; 60 | E254A8D319E7B4DE007BBE3C /* libAprilBeaconSDK.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libAprilBeaconSDK.a; sourceTree = ""; }; 61 | E26EB6AA197F5323007619B1 /* ABModifyViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ABModifyViewController.h; sourceTree = ""; }; 62 | E26EB6AB197F5323007619B1 /* ABModifyViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ABModifyViewController.m; sourceTree = ""; }; 63 | E26EB6AE197F5374007619B1 /* JVFloatLabeledTextField.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JVFloatLabeledTextField.h; sourceTree = ""; }; 64 | E26EB6AF197F5374007619B1 /* JVFloatLabeledTextField.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JVFloatLabeledTextField.m; sourceTree = ""; }; 65 | E26EB6B0197F5374007619B1 /* JVFloatLabeledTextView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JVFloatLabeledTextView.h; sourceTree = ""; }; 66 | E26EB6B1197F5374007619B1 /* JVFloatLabeledTextView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JVFloatLabeledTextView.m; sourceTree = ""; }; 67 | E26EB6B2197F5374007619B1 /* NSString+TextDirectionality.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+TextDirectionality.h"; sourceTree = ""; }; 68 | E26EB6B3197F5374007619B1 /* NSString+TextDirectionality.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+TextDirectionality.m"; sourceTree = ""; }; 69 | E2D134941ABA973400A7A3BF /* ABTransmitters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ABTransmitters.h; sourceTree = ""; }; 70 | E2D134951ABA973400A7A3BF /* ABTransmitters.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ABTransmitters.m; sourceTree = ""; }; 71 | E2D134961ABA973400A7A3BF /* ABUUIDTextField.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ABUUIDTextField.h; sourceTree = ""; }; 72 | E2D134971ABA973400A7A3BF /* ABUUIDTextField.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ABUUIDTextField.m; sourceTree = ""; }; 73 | E2ED5E511919E1F000C0BF2C /* AprilBeaconDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AprilBeaconDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 74 | E2ED5E541919E1F000C0BF2C /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 75 | E2ED5E561919E1F000C0BF2C /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 76 | E2ED5E581919E1F000C0BF2C /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 77 | E2ED5E5C1919E1F000C0BF2C /* AprilBeaconDemo-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "AprilBeaconDemo-Info.plist"; sourceTree = ""; }; 78 | E2ED5E5E1919E1F000C0BF2C /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 79 | E2ED5E601919E1F000C0BF2C /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 80 | E2ED5E621919E1F000C0BF2C /* AprilBeaconDemo-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "AprilBeaconDemo-Prefix.pch"; sourceTree = ""; }; 81 | E2ED5E631919E1F000C0BF2C /* ABAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ABAppDelegate.h; sourceTree = ""; }; 82 | E2ED5E641919E1F000C0BF2C /* ABAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ABAppDelegate.m; sourceTree = ""; }; 83 | E2ED5E671919E1F000C0BF2C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 84 | E2ED5E691919E1F000C0BF2C /* ABBeaconViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ABBeaconViewController.h; sourceTree = ""; }; 85 | E2ED5E6A1919E1F000C0BF2C /* ABBeaconViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ABBeaconViewController.m; sourceTree = ""; }; 86 | E2ED5E6C1919E1F000C0BF2C /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 87 | E2ED5E721919E1F000C0BF2C /* AprilBeaconDemoTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AprilBeaconDemoTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 88 | E2ED5E731919E1F000C0BF2C /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; 89 | E2ED5E7B1919E1F100C0BF2C /* AprilBeaconDemoTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "AprilBeaconDemoTests-Info.plist"; sourceTree = ""; }; 90 | E2ED5E7D1919E1F100C0BF2C /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 91 | E2ED5E7F1919E1F100C0BF2C /* AprilBeaconDemoTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AprilBeaconDemoTests.m; sourceTree = ""; }; 92 | E2ED5EDC191B32C600C0BF2C /* ABBluetoothViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ABBluetoothViewController.h; sourceTree = ""; }; 93 | E2ED5EDD191B32C600C0BF2C /* ABBluetoothViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ABBluetoothViewController.m; sourceTree = ""; }; 94 | E2ED5EDE191B32C600C0BF2C /* ABNotificationViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ABNotificationViewController.h; sourceTree = ""; }; 95 | E2ED5EDF191B32C600C0BF2C /* ABNotificationViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ABNotificationViewController.m; sourceTree = ""; }; 96 | E2ED5EE0191B32C600C0BF2C /* ABSelectDeviceViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ABSelectDeviceViewController.h; sourceTree = ""; }; 97 | E2ED5EE1191B32C600C0BF2C /* ABSelectDeviceViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ABSelectDeviceViewController.m; sourceTree = ""; }; 98 | E2FB5640199DA9780038CAA8 /* ABSensorViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ABSensorViewController.m; sourceTree = ""; }; 99 | E2FB5641199DA9780038CAA8 /* ABSensorViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ABSensorViewController.h; sourceTree = ""; }; 100 | E2FB5643199DA9A70038CAA8 /* ABSensorListViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ABSensorListViewController.h; sourceTree = ""; }; 101 | E2FB5644199DA9A70038CAA8 /* ABSensorListViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ABSensorListViewController.m; sourceTree = ""; }; 102 | E2FB5646199DAC2E0038CAA8 /* tile_floor.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = tile_floor.png; sourceTree = ""; }; 103 | /* End PBXFileReference section */ 104 | 105 | /* Begin PBXFrameworksBuildPhase section */ 106 | E2ED5E4E1919E1F000C0BF2C /* Frameworks */ = { 107 | isa = PBXFrameworksBuildPhase; 108 | buildActionMask = 2147483647; 109 | files = ( 110 | E2ED5E571919E1F000C0BF2C /* CoreGraphics.framework in Frameworks */, 111 | E2ED5E591919E1F000C0BF2C /* UIKit.framework in Frameworks */, 112 | E2ED5E551919E1F000C0BF2C /* Foundation.framework in Frameworks */, 113 | E254A8D419E7B4DE007BBE3C /* libAprilBeaconSDK.a in Frameworks */, 114 | ); 115 | runOnlyForDeploymentPostprocessing = 0; 116 | }; 117 | E2ED5E6F1919E1F000C0BF2C /* Frameworks */ = { 118 | isa = PBXFrameworksBuildPhase; 119 | buildActionMask = 2147483647; 120 | files = ( 121 | E2ED5E741919E1F000C0BF2C /* XCTest.framework in Frameworks */, 122 | E2ED5E761919E1F100C0BF2C /* UIKit.framework in Frameworks */, 123 | E2ED5E751919E1F100C0BF2C /* Foundation.framework in Frameworks */, 124 | ); 125 | runOnlyForDeploymentPostprocessing = 0; 126 | }; 127 | /* End PBXFrameworksBuildPhase section */ 128 | 129 | /* Begin PBXGroup section */ 130 | E254A8CC19E7B4DE007BBE3C /* AprilSDK */ = { 131 | isa = PBXGroup; 132 | children = ( 133 | E254A8CD19E7B4DE007BBE3C /* Headers */, 134 | E254A8D319E7B4DE007BBE3C /* libAprilBeaconSDK.a */, 135 | ); 136 | name = AprilSDK; 137 | path = ../AprilSDK; 138 | sourceTree = ""; 139 | }; 140 | E254A8CD19E7B4DE007BBE3C /* Headers */ = { 141 | isa = PBXGroup; 142 | children = ( 143 | E23E40791BD5DF2B00B17F49 /* ABBluetoothManager.h */, 144 | E23E407A1BD5DF2B00B17F49 /* ABDefinitions.h */, 145 | E254A8CE19E7B4DE007BBE3C /* ABBeacon.h */, 146 | 3EC0A1A11C3F659700945F45 /* ABBeaconManager.h */, 147 | 48A91E451AE78822007A1B43 /* ABError.h */, 148 | E254A8D019E7B4DE007BBE3C /* ABBeaconRegion.h */, 149 | E254A8D119E7B4DE007BBE3C /* ABSensor.h */, 150 | E254A8D219E7B4DE007BBE3C /* AprilBeaconSDK.h */, 151 | ); 152 | path = Headers; 153 | sourceTree = ""; 154 | }; 155 | E26EB6AD197F5374007619B1 /* JVFloatLabeledTextField */ = { 156 | isa = PBXGroup; 157 | children = ( 158 | E26EB6AE197F5374007619B1 /* JVFloatLabeledTextField.h */, 159 | E26EB6AF197F5374007619B1 /* JVFloatLabeledTextField.m */, 160 | E26EB6B0197F5374007619B1 /* JVFloatLabeledTextView.h */, 161 | E26EB6B1197F5374007619B1 /* JVFloatLabeledTextView.m */, 162 | E26EB6B2197F5374007619B1 /* NSString+TextDirectionality.h */, 163 | E26EB6B3197F5374007619B1 /* NSString+TextDirectionality.m */, 164 | ); 165 | path = JVFloatLabeledTextField; 166 | sourceTree = ""; 167 | }; 168 | E2ED5E481919E1F000C0BF2C = { 169 | isa = PBXGroup; 170 | children = ( 171 | E254A8CC19E7B4DE007BBE3C /* AprilSDK */, 172 | E2FB5646199DAC2E0038CAA8 /* tile_floor.png */, 173 | E26EB6AD197F5374007619B1 /* JVFloatLabeledTextField */, 174 | E2ED5E5A1919E1F000C0BF2C /* AprilBeaconDemo */, 175 | E2ED5E791919E1F100C0BF2C /* AprilBeaconDemoTests */, 176 | E2ED5E531919E1F000C0BF2C /* Frameworks */, 177 | E2ED5E521919E1F000C0BF2C /* Products */, 178 | ); 179 | sourceTree = ""; 180 | }; 181 | E2ED5E521919E1F000C0BF2C /* Products */ = { 182 | isa = PBXGroup; 183 | children = ( 184 | E2ED5E511919E1F000C0BF2C /* AprilBeaconDemo.app */, 185 | E2ED5E721919E1F000C0BF2C /* AprilBeaconDemoTests.xctest */, 186 | ); 187 | name = Products; 188 | sourceTree = ""; 189 | }; 190 | E2ED5E531919E1F000C0BF2C /* Frameworks */ = { 191 | isa = PBXGroup; 192 | children = ( 193 | E2ED5E541919E1F000C0BF2C /* Foundation.framework */, 194 | E2ED5E561919E1F000C0BF2C /* CoreGraphics.framework */, 195 | E2ED5E581919E1F000C0BF2C /* UIKit.framework */, 196 | E2ED5E731919E1F000C0BF2C /* XCTest.framework */, 197 | ); 198 | name = Frameworks; 199 | sourceTree = ""; 200 | }; 201 | E2ED5E5A1919E1F000C0BF2C /* AprilBeaconDemo */ = { 202 | isa = PBXGroup; 203 | children = ( 204 | E2D134941ABA973400A7A3BF /* ABTransmitters.h */, 205 | E2D134951ABA973400A7A3BF /* ABTransmitters.m */, 206 | E2D134961ABA973400A7A3BF /* ABUUIDTextField.h */, 207 | E2D134971ABA973400A7A3BF /* ABUUIDTextField.m */, 208 | E2FB5641199DA9780038CAA8 /* ABSensorViewController.h */, 209 | E2FB5640199DA9780038CAA8 /* ABSensorViewController.m */, 210 | E2FB5643199DA9A70038CAA8 /* ABSensorListViewController.h */, 211 | E2FB5644199DA9A70038CAA8 /* ABSensorListViewController.m */, 212 | E2ED5EDC191B32C600C0BF2C /* ABBluetoothViewController.h */, 213 | E2ED5EDD191B32C600C0BF2C /* ABBluetoothViewController.m */, 214 | E2ED5EDE191B32C600C0BF2C /* ABNotificationViewController.h */, 215 | E2ED5EDF191B32C600C0BF2C /* ABNotificationViewController.m */, 216 | E2ED5EE0191B32C600C0BF2C /* ABSelectDeviceViewController.h */, 217 | E2ED5EE1191B32C600C0BF2C /* ABSelectDeviceViewController.m */, 218 | E26EB6AA197F5323007619B1 /* ABModifyViewController.h */, 219 | E26EB6AB197F5323007619B1 /* ABModifyViewController.m */, 220 | E2ED5EE2191B32C600C0BF2C /* Model */, 221 | E2ED5E631919E1F000C0BF2C /* ABAppDelegate.h */, 222 | E2ED5E641919E1F000C0BF2C /* ABAppDelegate.m */, 223 | E2ED5E661919E1F000C0BF2C /* Main.storyboard */, 224 | E2ED5E691919E1F000C0BF2C /* ABBeaconViewController.h */, 225 | E2ED5E6A1919E1F000C0BF2C /* ABBeaconViewController.m */, 226 | E2ED5E6C1919E1F000C0BF2C /* Images.xcassets */, 227 | E2ED5E5B1919E1F000C0BF2C /* Supporting Files */, 228 | E23E40771BD5DC2B00B17F49 /* LaunchScreen.xib */, 229 | ); 230 | path = AprilBeaconDemo; 231 | sourceTree = ""; 232 | }; 233 | E2ED5E5B1919E1F000C0BF2C /* Supporting Files */ = { 234 | isa = PBXGroup; 235 | children = ( 236 | E2ED5E5C1919E1F000C0BF2C /* AprilBeaconDemo-Info.plist */, 237 | E2ED5E5D1919E1F000C0BF2C /* InfoPlist.strings */, 238 | E2ED5E601919E1F000C0BF2C /* main.m */, 239 | E2ED5E621919E1F000C0BF2C /* AprilBeaconDemo-Prefix.pch */, 240 | ); 241 | name = "Supporting Files"; 242 | sourceTree = ""; 243 | }; 244 | E2ED5E791919E1F100C0BF2C /* AprilBeaconDemoTests */ = { 245 | isa = PBXGroup; 246 | children = ( 247 | E2ED5E7F1919E1F100C0BF2C /* AprilBeaconDemoTests.m */, 248 | E2ED5E7A1919E1F100C0BF2C /* Supporting Files */, 249 | ); 250 | path = AprilBeaconDemoTests; 251 | sourceTree = ""; 252 | }; 253 | E2ED5E7A1919E1F100C0BF2C /* Supporting Files */ = { 254 | isa = PBXGroup; 255 | children = ( 256 | E2ED5E7B1919E1F100C0BF2C /* AprilBeaconDemoTests-Info.plist */, 257 | E2ED5E7C1919E1F100C0BF2C /* InfoPlist.strings */, 258 | ); 259 | name = "Supporting Files"; 260 | sourceTree = ""; 261 | }; 262 | E2ED5EE2191B32C600C0BF2C /* Model */ = { 263 | isa = PBXGroup; 264 | children = ( 265 | ); 266 | path = Model; 267 | sourceTree = ""; 268 | }; 269 | /* End PBXGroup section */ 270 | 271 | /* Begin PBXNativeTarget section */ 272 | E2ED5E501919E1F000C0BF2C /* AprilBeaconDemo */ = { 273 | isa = PBXNativeTarget; 274 | buildConfigurationList = E2ED5E831919E1F100C0BF2C /* Build configuration list for PBXNativeTarget "AprilBeaconDemo" */; 275 | buildPhases = ( 276 | E2ED5E4D1919E1F000C0BF2C /* Sources */, 277 | E2ED5E4E1919E1F000C0BF2C /* Frameworks */, 278 | E2ED5E4F1919E1F000C0BF2C /* Resources */, 279 | ); 280 | buildRules = ( 281 | ); 282 | dependencies = ( 283 | ); 284 | name = AprilBeaconDemo; 285 | productName = AprilBeaconDemo; 286 | productReference = E2ED5E511919E1F000C0BF2C /* AprilBeaconDemo.app */; 287 | productType = "com.apple.product-type.application"; 288 | }; 289 | E2ED5E711919E1F000C0BF2C /* AprilBeaconDemoTests */ = { 290 | isa = PBXNativeTarget; 291 | buildConfigurationList = E2ED5E861919E1F100C0BF2C /* Build configuration list for PBXNativeTarget "AprilBeaconDemoTests" */; 292 | buildPhases = ( 293 | E2ED5E6E1919E1F000C0BF2C /* Sources */, 294 | E2ED5E6F1919E1F000C0BF2C /* Frameworks */, 295 | E2ED5E701919E1F000C0BF2C /* Resources */, 296 | ); 297 | buildRules = ( 298 | ); 299 | dependencies = ( 300 | E2ED5E781919E1F100C0BF2C /* PBXTargetDependency */, 301 | ); 302 | name = AprilBeaconDemoTests; 303 | productName = AprilBeaconDemoTests; 304 | productReference = E2ED5E721919E1F000C0BF2C /* AprilBeaconDemoTests.xctest */; 305 | productType = "com.apple.product-type.bundle.unit-test"; 306 | }; 307 | /* End PBXNativeTarget section */ 308 | 309 | /* Begin PBXProject section */ 310 | E2ED5E491919E1F000C0BF2C /* Project object */ = { 311 | isa = PBXProject; 312 | attributes = { 313 | CLASSPREFIX = AB; 314 | LastUpgradeCheck = 0720; 315 | ORGANIZATIONNAME = AprilBrother; 316 | TargetAttributes = { 317 | E2ED5E501919E1F000C0BF2C = { 318 | DevelopmentTeam = B394B8PA37; 319 | SystemCapabilities = { 320 | com.apple.BackgroundModes = { 321 | enabled = 0; 322 | }; 323 | }; 324 | }; 325 | E2ED5E711919E1F000C0BF2C = { 326 | TestTargetID = E2ED5E501919E1F000C0BF2C; 327 | }; 328 | }; 329 | }; 330 | buildConfigurationList = E2ED5E4C1919E1F000C0BF2C /* Build configuration list for PBXProject "AprilBeaconDemo" */; 331 | compatibilityVersion = "Xcode 3.2"; 332 | developmentRegion = English; 333 | hasScannedForEncodings = 0; 334 | knownRegions = ( 335 | en, 336 | Base, 337 | ); 338 | mainGroup = E2ED5E481919E1F000C0BF2C; 339 | productRefGroup = E2ED5E521919E1F000C0BF2C /* Products */; 340 | projectDirPath = ""; 341 | projectRoot = ""; 342 | targets = ( 343 | E2ED5E501919E1F000C0BF2C /* AprilBeaconDemo */, 344 | E2ED5E711919E1F000C0BF2C /* AprilBeaconDemoTests */, 345 | ); 346 | }; 347 | /* End PBXProject section */ 348 | 349 | /* Begin PBXResourcesBuildPhase section */ 350 | E2ED5E4F1919E1F000C0BF2C /* Resources */ = { 351 | isa = PBXResourcesBuildPhase; 352 | buildActionMask = 2147483647; 353 | files = ( 354 | E23E40781BD5DC2B00B17F49 /* LaunchScreen.xib in Resources */, 355 | E2FB5647199DAC2E0038CAA8 /* tile_floor.png in Resources */, 356 | E2ED5E6D1919E1F000C0BF2C /* Images.xcassets in Resources */, 357 | E2ED5E5F1919E1F000C0BF2C /* InfoPlist.strings in Resources */, 358 | E2ED5E681919E1F000C0BF2C /* Main.storyboard in Resources */, 359 | ); 360 | runOnlyForDeploymentPostprocessing = 0; 361 | }; 362 | E2ED5E701919E1F000C0BF2C /* Resources */ = { 363 | isa = PBXResourcesBuildPhase; 364 | buildActionMask = 2147483647; 365 | files = ( 366 | E2ED5E7E1919E1F100C0BF2C /* InfoPlist.strings in Resources */, 367 | ); 368 | runOnlyForDeploymentPostprocessing = 0; 369 | }; 370 | /* End PBXResourcesBuildPhase section */ 371 | 372 | /* Begin PBXSourcesBuildPhase section */ 373 | E2ED5E4D1919E1F000C0BF2C /* Sources */ = { 374 | isa = PBXSourcesBuildPhase; 375 | buildActionMask = 2147483647; 376 | files = ( 377 | E26EB6B4197F5374007619B1 /* JVFloatLabeledTextField.m in Sources */, 378 | E2ED5E611919E1F000C0BF2C /* main.m in Sources */, 379 | E2ED5EE7191B32C600C0BF2C /* ABSelectDeviceViewController.m in Sources */, 380 | E2ED5E6B1919E1F000C0BF2C /* ABBeaconViewController.m in Sources */, 381 | E26EB6B5197F5374007619B1 /* JVFloatLabeledTextView.m in Sources */, 382 | E26EB6B6197F5374007619B1 /* NSString+TextDirectionality.m in Sources */, 383 | E2D134981ABA973400A7A3BF /* ABTransmitters.m in Sources */, 384 | E2ED5EE5191B32C600C0BF2C /* ABBluetoothViewController.m in Sources */, 385 | E2FB5642199DA9780038CAA8 /* ABSensorViewController.m in Sources */, 386 | E2ED5EE6191B32C600C0BF2C /* ABNotificationViewController.m in Sources */, 387 | E26EB6AC197F5323007619B1 /* ABModifyViewController.m in Sources */, 388 | E2ED5E651919E1F000C0BF2C /* ABAppDelegate.m in Sources */, 389 | E2D134991ABA973400A7A3BF /* ABUUIDTextField.m in Sources */, 390 | E2FB5645199DA9A70038CAA8 /* ABSensorListViewController.m in Sources */, 391 | ); 392 | runOnlyForDeploymentPostprocessing = 0; 393 | }; 394 | E2ED5E6E1919E1F000C0BF2C /* Sources */ = { 395 | isa = PBXSourcesBuildPhase; 396 | buildActionMask = 2147483647; 397 | files = ( 398 | E2ED5E801919E1F100C0BF2C /* AprilBeaconDemoTests.m in Sources */, 399 | ); 400 | runOnlyForDeploymentPostprocessing = 0; 401 | }; 402 | /* End PBXSourcesBuildPhase section */ 403 | 404 | /* Begin PBXTargetDependency section */ 405 | E2ED5E781919E1F100C0BF2C /* PBXTargetDependency */ = { 406 | isa = PBXTargetDependency; 407 | target = E2ED5E501919E1F000C0BF2C /* AprilBeaconDemo */; 408 | targetProxy = E2ED5E771919E1F100C0BF2C /* PBXContainerItemProxy */; 409 | }; 410 | /* End PBXTargetDependency section */ 411 | 412 | /* Begin PBXVariantGroup section */ 413 | E2ED5E5D1919E1F000C0BF2C /* InfoPlist.strings */ = { 414 | isa = PBXVariantGroup; 415 | children = ( 416 | E2ED5E5E1919E1F000C0BF2C /* en */, 417 | ); 418 | name = InfoPlist.strings; 419 | sourceTree = ""; 420 | }; 421 | E2ED5E661919E1F000C0BF2C /* Main.storyboard */ = { 422 | isa = PBXVariantGroup; 423 | children = ( 424 | E2ED5E671919E1F000C0BF2C /* Base */, 425 | ); 426 | name = Main.storyboard; 427 | sourceTree = ""; 428 | }; 429 | E2ED5E7C1919E1F100C0BF2C /* InfoPlist.strings */ = { 430 | isa = PBXVariantGroup; 431 | children = ( 432 | E2ED5E7D1919E1F100C0BF2C /* en */, 433 | ); 434 | name = InfoPlist.strings; 435 | sourceTree = ""; 436 | }; 437 | /* End PBXVariantGroup section */ 438 | 439 | /* Begin XCBuildConfiguration section */ 440 | E2ED5E811919E1F100C0BF2C /* Debug */ = { 441 | isa = XCBuildConfiguration; 442 | buildSettings = { 443 | ALWAYS_SEARCH_USER_PATHS = NO; 444 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 445 | CLANG_CXX_LIBRARY = "libc++"; 446 | CLANG_ENABLE_MODULES = YES; 447 | CLANG_ENABLE_OBJC_ARC = YES; 448 | CLANG_WARN_BOOL_CONVERSION = YES; 449 | CLANG_WARN_CONSTANT_CONVERSION = YES; 450 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 451 | CLANG_WARN_EMPTY_BODY = YES; 452 | CLANG_WARN_ENUM_CONVERSION = YES; 453 | CLANG_WARN_INT_CONVERSION = YES; 454 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 455 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 456 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 457 | COPY_PHASE_STRIP = NO; 458 | ENABLE_TESTABILITY = YES; 459 | GCC_C_LANGUAGE_STANDARD = gnu99; 460 | GCC_DYNAMIC_NO_PIC = NO; 461 | GCC_OPTIMIZATION_LEVEL = 0; 462 | GCC_PREPROCESSOR_DEFINITIONS = ( 463 | "DEBUG=1", 464 | "$(inherited)", 465 | ); 466 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 467 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 468 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 469 | GCC_WARN_UNDECLARED_SELECTOR = YES; 470 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 471 | GCC_WARN_UNUSED_FUNCTION = YES; 472 | GCC_WARN_UNUSED_VARIABLE = YES; 473 | IPHONEOS_DEPLOYMENT_TARGET = 7.1; 474 | ONLY_ACTIVE_ARCH = YES; 475 | PROVISIONING_PROFILE = ""; 476 | SDKROOT = iphoneos; 477 | }; 478 | name = Debug; 479 | }; 480 | E2ED5E821919E1F100C0BF2C /* Release */ = { 481 | isa = XCBuildConfiguration; 482 | buildSettings = { 483 | ALWAYS_SEARCH_USER_PATHS = NO; 484 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 485 | CLANG_CXX_LIBRARY = "libc++"; 486 | CLANG_ENABLE_MODULES = YES; 487 | CLANG_ENABLE_OBJC_ARC = YES; 488 | CLANG_WARN_BOOL_CONVERSION = YES; 489 | CLANG_WARN_CONSTANT_CONVERSION = YES; 490 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 491 | CLANG_WARN_EMPTY_BODY = YES; 492 | CLANG_WARN_ENUM_CONVERSION = YES; 493 | CLANG_WARN_INT_CONVERSION = YES; 494 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 495 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 496 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 497 | COPY_PHASE_STRIP = YES; 498 | ENABLE_NS_ASSERTIONS = NO; 499 | GCC_C_LANGUAGE_STANDARD = gnu99; 500 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 501 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 502 | GCC_WARN_UNDECLARED_SELECTOR = YES; 503 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 504 | GCC_WARN_UNUSED_FUNCTION = YES; 505 | GCC_WARN_UNUSED_VARIABLE = YES; 506 | IPHONEOS_DEPLOYMENT_TARGET = 7.1; 507 | PROVISIONING_PROFILE = ""; 508 | SDKROOT = iphoneos; 509 | VALIDATE_PRODUCT = YES; 510 | }; 511 | name = Release; 512 | }; 513 | E2ED5E841919E1F100C0BF2C /* Debug */ = { 514 | isa = XCBuildConfiguration; 515 | buildSettings = { 516 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 517 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 518 | CODE_SIGN_IDENTITY = "iPhone Developer"; 519 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 520 | ENABLE_BITCODE = NO; 521 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 522 | GCC_PREFIX_HEADER = "AprilBeaconDemo/AprilBeaconDemo-Prefix.pch"; 523 | HEADER_SEARCH_PATHS = ( 524 | "$(inherited)", 525 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, 526 | ../AprilSDK/Headers/, 527 | ); 528 | INFOPLIST_FILE = "AprilBeaconDemo/AprilBeaconDemo-Info.plist"; 529 | LIBRARY_SEARCH_PATHS = ( 530 | "$(inherited)", 531 | "$(PROJECT_DIR)", 532 | ../AprilSDK, 533 | "/Users/liaojinhua/Documents/AprilBrother/WorkSpace/AprilBeacon-iOS-SDK/AprilSDK", 534 | ); 535 | OTHER_LDFLAGS = "-all_load"; 536 | PRODUCT_BUNDLE_IDENTIFIER = "com.aprilbrother.${PRODUCT_NAME:rfc1034identifier}"; 537 | PRODUCT_NAME = "$(TARGET_NAME)"; 538 | PROVISIONING_PROFILE = ""; 539 | WRAPPER_EXTENSION = app; 540 | }; 541 | name = Debug; 542 | }; 543 | E2ED5E851919E1F100C0BF2C /* Release */ = { 544 | isa = XCBuildConfiguration; 545 | buildSettings = { 546 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 547 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 548 | CODE_SIGN_IDENTITY = "iPhone Developer"; 549 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 550 | ENABLE_BITCODE = NO; 551 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 552 | GCC_PREFIX_HEADER = "AprilBeaconDemo/AprilBeaconDemo-Prefix.pch"; 553 | HEADER_SEARCH_PATHS = ( 554 | "$(inherited)", 555 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, 556 | ../AprilSDK/Headers/, 557 | ); 558 | INFOPLIST_FILE = "AprilBeaconDemo/AprilBeaconDemo-Info.plist"; 559 | LIBRARY_SEARCH_PATHS = ( 560 | "$(inherited)", 561 | "$(PROJECT_DIR)", 562 | ../AprilSDK, 563 | "/Users/liaojinhua/Documents/AprilBrother/WorkSpace/AprilBeacon-iOS-SDK/AprilSDK", 564 | ); 565 | OTHER_LDFLAGS = "-all_load"; 566 | PRODUCT_BUNDLE_IDENTIFIER = "com.aprilbrother.${PRODUCT_NAME:rfc1034identifier}"; 567 | PRODUCT_NAME = "$(TARGET_NAME)"; 568 | PROVISIONING_PROFILE = ""; 569 | WRAPPER_EXTENSION = app; 570 | }; 571 | name = Release; 572 | }; 573 | E2ED5E871919E1F100C0BF2C /* Debug */ = { 574 | isa = XCBuildConfiguration; 575 | buildSettings = { 576 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/AprilBeaconDemo.app/AprilBeaconDemo"; 577 | FRAMEWORK_SEARCH_PATHS = ( 578 | "$(SDKROOT)/Developer/Library/Frameworks", 579 | "$(inherited)", 580 | "$(DEVELOPER_FRAMEWORKS_DIR)", 581 | ); 582 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 583 | GCC_PREFIX_HEADER = "AprilBeaconDemo/AprilBeaconDemo-Prefix.pch"; 584 | GCC_PREPROCESSOR_DEFINITIONS = ( 585 | "DEBUG=1", 586 | "$(inherited)", 587 | ); 588 | INFOPLIST_FILE = "AprilBeaconDemoTests/AprilBeaconDemoTests-Info.plist"; 589 | PRODUCT_BUNDLE_IDENTIFIER = "com.aprilbrother.${PRODUCT_NAME:rfc1034identifier}"; 590 | PRODUCT_NAME = "$(TARGET_NAME)"; 591 | TEST_HOST = "$(BUNDLE_LOADER)"; 592 | WRAPPER_EXTENSION = xctest; 593 | }; 594 | name = Debug; 595 | }; 596 | E2ED5E881919E1F100C0BF2C /* Release */ = { 597 | isa = XCBuildConfiguration; 598 | buildSettings = { 599 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/AprilBeaconDemo.app/AprilBeaconDemo"; 600 | FRAMEWORK_SEARCH_PATHS = ( 601 | "$(SDKROOT)/Developer/Library/Frameworks", 602 | "$(inherited)", 603 | "$(DEVELOPER_FRAMEWORKS_DIR)", 604 | ); 605 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 606 | GCC_PREFIX_HEADER = "AprilBeaconDemo/AprilBeaconDemo-Prefix.pch"; 607 | INFOPLIST_FILE = "AprilBeaconDemoTests/AprilBeaconDemoTests-Info.plist"; 608 | PRODUCT_BUNDLE_IDENTIFIER = "com.aprilbrother.${PRODUCT_NAME:rfc1034identifier}"; 609 | PRODUCT_NAME = "$(TARGET_NAME)"; 610 | TEST_HOST = "$(BUNDLE_LOADER)"; 611 | WRAPPER_EXTENSION = xctest; 612 | }; 613 | name = Release; 614 | }; 615 | /* End XCBuildConfiguration section */ 616 | 617 | /* Begin XCConfigurationList section */ 618 | E2ED5E4C1919E1F000C0BF2C /* Build configuration list for PBXProject "AprilBeaconDemo" */ = { 619 | isa = XCConfigurationList; 620 | buildConfigurations = ( 621 | E2ED5E811919E1F100C0BF2C /* Debug */, 622 | E2ED5E821919E1F100C0BF2C /* Release */, 623 | ); 624 | defaultConfigurationIsVisible = 0; 625 | defaultConfigurationName = Release; 626 | }; 627 | E2ED5E831919E1F100C0BF2C /* Build configuration list for PBXNativeTarget "AprilBeaconDemo" */ = { 628 | isa = XCConfigurationList; 629 | buildConfigurations = ( 630 | E2ED5E841919E1F100C0BF2C /* Debug */, 631 | E2ED5E851919E1F100C0BF2C /* Release */, 632 | ); 633 | defaultConfigurationIsVisible = 0; 634 | defaultConfigurationName = Release; 635 | }; 636 | E2ED5E861919E1F100C0BF2C /* Build configuration list for PBXNativeTarget "AprilBeaconDemoTests" */ = { 637 | isa = XCConfigurationList; 638 | buildConfigurations = ( 639 | E2ED5E871919E1F100C0BF2C /* Debug */, 640 | E2ED5E881919E1F100C0BF2C /* Release */, 641 | ); 642 | defaultConfigurationIsVisible = 0; 643 | defaultConfigurationName = Release; 644 | }; 645 | /* End XCConfigurationList section */ 646 | }; 647 | rootObject = E2ED5E491919E1F000C0BF2C /* Project object */; 648 | } 649 | -------------------------------------------------------------------------------- /AprilBeaconDemo/AprilBeaconDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /AprilBeaconDemo/AprilBeaconDemo.xcodeproj/project.xcworkspace/xcshareddata/AprilBeaconDemo.xccheckout: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDESourceControlProjectFavoriteDictionaryKey 6 | 7 | IDESourceControlProjectIdentifier 8 | 5A1B7596-9368-4510-92B2-81838DF9A912 9 | IDESourceControlProjectName 10 | AprilBeaconDemo 11 | IDESourceControlProjectOriginsDictionary 12 | 13 | 789059A45EC79475044DD26E897CB209CC1DE51C 14 | github.com:AprilBrother/AprilBeacon-iOS-SDK.git 15 | 16 | IDESourceControlProjectPath 17 | AprilBeaconDemo/AprilBeaconDemo.xcodeproj 18 | IDESourceControlProjectRelativeInstallPathDictionary 19 | 20 | 789059A45EC79475044DD26E897CB209CC1DE51C 21 | ../../.. 22 | 23 | IDESourceControlProjectURL 24 | github.com:AprilBrother/AprilBeacon-iOS-SDK.git 25 | IDESourceControlProjectVersion 26 | 111 27 | IDESourceControlProjectWCCIdentifier 28 | 789059A45EC79475044DD26E897CB209CC1DE51C 29 | IDESourceControlProjectWCConfigurations 30 | 31 | 32 | IDESourceControlRepositoryExtensionIdentifierKey 33 | public.vcs.git 34 | IDESourceControlWCCIdentifierKey 35 | 789059A45EC79475044DD26E897CB209CC1DE51C 36 | IDESourceControlWCCName 37 | AprilBeacon-iOS-SDK 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /AprilBeaconDemo/AprilBeaconDemo/ABAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // ABAppDelegate.h 3 | // AprilBeaconDemo 4 | // 5 | // Created by liaojinhua on 14-5-7. 6 | // Copyright (c) 2014年 AprilBrother. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface ABAppDelegate : UIResponder 13 | 14 | @property (strong, nonatomic) UIWindow *window; 15 | @property (nonatomic, strong) ABBeaconManager *beaconManger; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /AprilBeaconDemo/AprilBeaconDemo/ABAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // ABAppDelegate.m 3 | // AprilBeaconDemo 4 | // 5 | // Created by liaojinhua on 14-5-7. 6 | // Copyright (c) 2014年 AprilBrother. All rights reserved. 7 | // 8 | 9 | #import "ABAppDelegate.h" 10 | 11 | @interface ABAppDelegate () 12 | 13 | @property (nonatomic) UIBackgroundTaskIdentifier taskId; 14 | 15 | @end 16 | 17 | @implementation ABAppDelegate 18 | 19 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 20 | { 21 | // Override point for customization after application launch. 22 | self.beaconManger = [[ABBeaconManager alloc] init]; 23 | self.beaconManger.delegate = self; 24 | if ([UIApplication instancesRespondToSelector:@selector(registerUserNotificationSettings:)]){ 25 | [application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound categories:nil]]; 26 | } 27 | 28 | return YES; 29 | } 30 | 31 | - (void)applicationWillResignActive:(UIApplication *)application 32 | { 33 | // 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. 34 | // 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. 35 | } 36 | 37 | - (void)applicationDidEnterBackground:(UIApplication *)application 38 | { 39 | // 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. 40 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 41 | self.taskId = [application beginBackgroundTaskWithExpirationHandler:^(void) { 42 | [application endBackgroundTask:self.taskId]; 43 | self.taskId = UIBackgroundTaskInvalid; 44 | }]; 45 | } 46 | 47 | - (void)applicationWillEnterForeground:(UIApplication *)application 48 | { 49 | // 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. 50 | } 51 | 52 | - (void)applicationDidBecomeActive:(UIApplication *)application 53 | { 54 | // 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. 55 | } 56 | 57 | - (void)applicationWillTerminate:(UIApplication *)application 58 | { 59 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 60 | } 61 | 62 | - (void)beaconManager:(ABBeaconManager *)manager didEnterRegion:(ABBeaconRegion *)region 63 | { 64 | UILocalNotification *notification = [[UILocalNotification alloc] init]; 65 | notification.alertBody = @"Enter monitoring region"; 66 | notification.soundName = UILocalNotificationDefaultSoundName; 67 | [[UIApplication sharedApplication] presentLocalNotificationNow:notification]; 68 | } 69 | 70 | - (void)beaconManager:(ABBeaconManager *)manager didExitRegion:(ABBeaconRegion *)region 71 | { 72 | UILocalNotification *notification = [[UILocalNotification alloc] init]; 73 | notification.alertBody = @"Exit monitoring region"; 74 | notification.soundName = UILocalNotificationDefaultSoundName; 75 | [[UIApplication sharedApplication] presentLocalNotificationNow:notification]; 76 | } 77 | 78 | @end 79 | -------------------------------------------------------------------------------- /AprilBeaconDemo/AprilBeaconDemo/ABBeaconViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ABViewController.h 3 | // TestSDKPod 4 | // 5 | // Created by liaojinhua on 14-5-7. 6 | // Copyright (c) 2014年 AprilBrother. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface ABBeaconViewController : UITableViewController 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /AprilBeaconDemo/AprilBeaconDemo/ABBeaconViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ABViewController.m 3 | // TestSDKPod 4 | // 5 | // Created by liaojinhua on 14-5-7. 6 | // Copyright (c) 2014年 AprilBrother. All rights reserved. 7 | // 8 | 9 | #import "ABBeaconViewController.h" 10 | #import "ABTransmitters.h" 11 | 12 | @interface ABBeaconViewController () 13 | 14 | @property (nonatomic, strong) ABBeaconManager *beaconManager; 15 | @property (nonatomic, strong) NSMutableDictionary *tableData; 16 | 17 | @end 18 | 19 | @implementation ABBeaconViewController 20 | 21 | - (id)initWithCoder:(NSCoder *)aDecoder 22 | { 23 | if (self = [super initWithCoder:aDecoder]) { 24 | self.beaconManager = [[ABBeaconManager alloc] init]; 25 | self.beaconManager.delegate = self; 26 | 27 | [self.beaconManager requestAlwaysAuthorization]; 28 | 29 | _tableData = [NSMutableDictionary dictionary]; 30 | } 31 | return self; 32 | } 33 | 34 | - (void)viewDidLoad 35 | { 36 | [super viewDidLoad]; 37 | // Do any additional setup after loading the view, typically from a nib. 38 | 39 | self.refreshControl = [[UIRefreshControl alloc] init]; 40 | [self.refreshControl addTarget:self 41 | action:@selector(startRangeBeacons) 42 | forControlEvents:UIControlEventValueChanged]; 43 | } 44 | 45 | - (void)viewWillAppear:(BOOL)animated 46 | { 47 | [super viewWillAppear:animated]; 48 | [self startRangeBeacons]; 49 | } 50 | 51 | - (void)viewWillDisappear:(BOOL)animated 52 | { 53 | [super viewWillDisappear:animated]; 54 | [self stopRangeBeacons]; 55 | } 56 | 57 | - (void)didReceiveMemoryWarning 58 | { 59 | [super didReceiveMemoryWarning]; 60 | // Dispose of any resources that can be recreated. 61 | } 62 | 63 | #pragma mark - Table view data source 64 | 65 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 66 | { 67 | return [[_tableData allValues][section] count]; 68 | } 69 | 70 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 71 | { 72 | return _tableData.count; 73 | } 74 | 75 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 76 | { 77 | ABBeacon *beacon = [_tableData allValues][indexPath.section][indexPath.row]; 78 | 79 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"beaconCell"]; 80 | 81 | cell.textLabel.text = [beacon.proximityUUID UUIDString]; 82 | 83 | NSString *proximity; 84 | switch (beacon.proximity) { 85 | case CLProximityFar: 86 | proximity = @"Far"; 87 | break; 88 | case CLProximityImmediate: 89 | proximity = @"Immediate"; 90 | break; 91 | case CLProximityNear: 92 | proximity = @"Near"; 93 | break; 94 | default: 95 | proximity = @"Unknown"; 96 | break; 97 | } 98 | cell.detailTextLabel.text = [NSString stringWithFormat:@"Major: %@, Minor: %@, Acc: %.2fm, proximity=%@", beacon.major, beacon.minor, [beacon.distance floatValue], proximity]; 99 | 100 | return cell; 101 | } 102 | 103 | #pragma mark - ABBeaconManagerDelegate 104 | - (void)beaconManager:(ABBeaconManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(ABBeaconRegion *)region 105 | { 106 | NSLog(@"beacons = %@", beacons); 107 | [self.refreshControl endRefreshing]; 108 | [_tableData removeObjectForKey:region]; 109 | [_tableData setObject:beacons forKey:region]; 110 | [self.tableView reloadData]; 111 | } 112 | 113 | - (void)beaconManager:(ABBeaconManager *)manager rangingBeaconsDidFailForRegion:(ABBeaconRegion *)region withError:(NSError *)error 114 | { 115 | [self.refreshControl endRefreshing]; 116 | [_tableData removeObjectForKey:region]; 117 | [self.tableView reloadData]; 118 | } 119 | 120 | #pragma mark - Custom methods 121 | 122 | - (void)startRangeBeacons 123 | { 124 | [self stopRangeBeacons]; 125 | 126 | ABTransmitters *tran = [ABTransmitters sharedTransmitters]; 127 | [[tran transmitters] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 128 | NSUUID *proximityUUID = [[NSUUID alloc] initWithUUIDString:obj[@"uuid"]]; 129 | NSString *regionIdentifier = obj[@"uuid"]; 130 | 131 | ABBeaconRegion *beaconRegion; 132 | beaconRegion = [[ABBeaconRegion alloc] initWithProximityUUID:proximityUUID 133 | identifier:regionIdentifier]; 134 | beaconRegion.notifyOnEntry = YES; 135 | beaconRegion.notifyOnExit = YES; 136 | beaconRegion.notifyEntryStateOnDisplay = YES; 137 | [_beaconManager startRangingBeaconsInRegion:beaconRegion]; 138 | }]; 139 | } 140 | 141 | - (void)stopRangeBeacons 142 | { 143 | ABTransmitters *tran = [ABTransmitters sharedTransmitters]; 144 | [[tran transmitters] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 145 | NSUUID *proximityUUID = [[NSUUID alloc] initWithUUIDString:obj[@"uuid"]]; 146 | NSString *regionIdentifier = obj[@"uuid"]; 147 | 148 | ABBeaconRegion *beaconRegion; 149 | beaconRegion = [[ABBeaconRegion alloc] initWithProximityUUID:proximityUUID 150 | identifier:regionIdentifier]; 151 | [_beaconManager stopRangingBeaconsInRegion:beaconRegion]; 152 | }]; 153 | 154 | } 155 | 156 | @end 157 | -------------------------------------------------------------------------------- /AprilBeaconDemo/AprilBeaconDemo/ABBluetoothViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ABBluetoothViewController.h 3 | // TestSDKPod 4 | // 5 | // Created by liaojinhua on 14-5-8. 6 | // Copyright (c) 2014年 AprilBrother. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AprilBeaconSDK.h" 11 | 12 | @interface ABBluetoothViewController : UITableViewController 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /AprilBeaconDemo/AprilBeaconDemo/ABBluetoothViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ABBluetoothViewController.m 3 | // TestSDKPod 4 | // 5 | // Created by liaojinhua on 14-5-8. 6 | // Copyright (c) 2014年 AprilBrother. All rights reserved. 7 | // 8 | 9 | #import "ABBluetoothViewController.h" 10 | #import "ABModifyViewController.h" 11 | 12 | @interface ABBluetoothViewController () 13 | 14 | @property (nonatomic, strong) ABBluetoothManager *beaconManager; 15 | @property (nonatomic, strong) NSMutableArray *tableData; 16 | 17 | @end 18 | 19 | @implementation ABBluetoothViewController 20 | 21 | - (void)viewDidLoad 22 | { 23 | [super viewDidLoad]; 24 | 25 | self.beaconManager = [[ABBluetoothManager alloc] init]; 26 | self.beaconManager.delegate = self; 27 | 28 | _tableData = [NSMutableArray array]; 29 | 30 | self.refreshControl = [[UIRefreshControl alloc] init]; 31 | [self.refreshControl addTarget:self 32 | action:@selector(startRangeBeacons) 33 | forControlEvents:UIControlEventValueChanged]; 34 | 35 | [self.beaconManager addCustomBeaconNameFilter:@"aikaka"]; 36 | } 37 | 38 | - (void)viewWillAppear:(BOOL)animated 39 | { 40 | [super viewWillAppear:animated]; 41 | [self startRangeBeacons]; 42 | } 43 | 44 | - (void)viewWillDisappear:(BOOL)animated 45 | { 46 | [super viewWillDisappear:animated]; 47 | [self stopRangeBeacons]; 48 | } 49 | 50 | - (void)didReceiveMemoryWarning 51 | { 52 | [super didReceiveMemoryWarning]; 53 | // Dispose of any resources that can be recreated. 54 | } 55 | 56 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 57 | { 58 | if ([segue.identifier isEqualToString:@"ModifySegue"]) { 59 | ABModifyViewController *vc = segue.destinationViewController; 60 | vc.beacon = sender; 61 | } 62 | } 63 | 64 | #pragma mark - Table view data source 65 | 66 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 67 | { 68 | return [_tableData count]; 69 | } 70 | 71 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 72 | { 73 | ABBeacon *beacon = _tableData[indexPath.row]; 74 | CBPeripheral *peripheral = beacon.peripheral; 75 | 76 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"beaconCell"]; 77 | 78 | cell.textLabel.text = peripheral.name; 79 | NSMutableString *detailString = [[NSMutableString alloc] init]; 80 | 81 | // fot the newest EEK iBeacon, you can get Major, Minor, Mac Address , battery level when scan iBeacons. 82 | if (beacon.major) { 83 | [detailString appendFormat:@"Major:%@ ",beacon.major]; 84 | } 85 | if (beacon.minor) { 86 | [detailString appendFormat:@"Minor:%@ ",beacon.minor]; 87 | } 88 | if (beacon.macAddress) { 89 | [detailString appendFormat:@"Mac:%@ ",beacon.macAddress]; 90 | } 91 | if (beacon.batteryLevel) { 92 | [detailString appendFormat:@"Battery:%@ ", beacon.batteryLevel]; 93 | } 94 | if (beacon.rssi == 127) { 95 | cell.userInteractionEnabled = NO; 96 | cell.textLabel.textColor = [UIColor lightGrayColor]; 97 | 98 | [detailString appendFormat:@"rssi : "]; 99 | } else { 100 | cell.userInteractionEnabled = YES; 101 | cell.textLabel.textColor = [UIColor blackColor]; 102 | [detailString appendFormat:@"rssi : %ld", (long)beacon.rssi]; 103 | } 104 | 105 | cell.detailTextLabel.text = detailString; 106 | cell.detailTextLabel.numberOfLines = 0; 107 | 108 | 109 | return cell; 110 | } 111 | 112 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 113 | { 114 | [self performSegueWithIdentifier:@"ModifySegue" sender:_tableData[indexPath.row]]; 115 | } 116 | 117 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 118 | { 119 | return 60; 120 | } 121 | 122 | 123 | #pragma mark - ABBeaconManagerDelegate 124 | - (void)beaconManager:(ABBeaconManager *)manager didDiscoverBeacons:(NSArray *)beacons{ 125 | [self.refreshControl endRefreshing]; 126 | [_tableData removeAllObjects]; 127 | [_tableData addObjectsFromArray:beacons]; 128 | [self.tableView reloadData]; 129 | } 130 | 131 | #pragma mark - Custom methods 132 | 133 | - (void)startRangeBeacons 134 | { 135 | [self stopRangeBeacons]; 136 | [_beaconManager startAprilBeaconsDiscovery]; 137 | // [_beaconManager startAprilSensorsDiscovery]; // only find april sensors 138 | // [_beaconManager startAprilLightDiscovery]; // only find april lights 139 | } 140 | 141 | - (void)stopRangeBeacons 142 | { 143 | [_beaconManager stopAprilBeaconDiscovery]; 144 | } 145 | 146 | 147 | @end 148 | -------------------------------------------------------------------------------- /AprilBeaconDemo/AprilBeaconDemo/ABModifyViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ABModifyViewController.h 3 | // Examples 4 | // 5 | // Created by liaojinhua on 14-7-2. 6 | // Copyright (c) 2014年 li shuai. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import "JVFloatLabeledTextField.h" 12 | #import "ABUUIDTextField.h" 13 | 14 | @interface ABModifyViewController : UITableViewController 15 | 16 | @property (nonatomic, strong) ABBeacon *beacon; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /AprilBeaconDemo/AprilBeaconDemo/ABModifyViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ABModifyViewController.m 3 | // Examples 4 | // 5 | // Created by liaojinhua on 14-7-2. 6 | // Copyright (c) 2014年 li shuai. All rights reserved. 7 | // 8 | 9 | #import "ABModifyViewController.h" 10 | 11 | #define kTxPowerCellIndex 0 12 | 13 | typedef enum { 14 | BBTxPower0DBM = 0, 15 | BBTxPower4DBM = 1, 16 | BBTxPowerMinus6DBM = 2, 17 | BBTxPowerMinus23DBM = 3 18 | } BBTxPower; 19 | 20 | @interface ABModifyViewController () 21 | 22 | 23 | @end 24 | 25 | @implementation ABModifyViewController 26 | 27 | - (id)initWithStyle:(UITableViewStyle)style 28 | { 29 | self = [super initWithStyle:style]; 30 | if (self) { 31 | // Custom initialization 32 | } 33 | return self; 34 | } 35 | 36 | - (void)viewDidLoad 37 | { 38 | [super viewDidLoad]; 39 | self.beacon.delegate = self; 40 | [self.beacon connectToBeacon]; 41 | } 42 | 43 | - (void)viewWillDisappear:(BOOL)animated 44 | { 45 | [super viewWillDisappear:animated]; 46 | [self.beacon disconnectBeacon]; 47 | self.beacon.delegate = nil; 48 | } 49 | 50 | - (void)didReceiveMemoryWarning 51 | { 52 | [super didReceiveMemoryWarning]; 53 | // Dispose of any resources that can be recreated. 54 | } 55 | 56 | 57 | #pragma mark - ABBeaconDelegate 58 | 59 | - (void)beaconDidConnected:(ABBeacon *)beacon withError:(NSError *)error 60 | { 61 | if (error) { 62 | NSLog(@"connect error: %@", error); 63 | } 64 | } 65 | 66 | - (void)beaconDidDisconnect:(ABBeacon *)beacon withError:(NSError *)error 67 | { 68 | 69 | } 70 | 71 | #pragma mark - UITableViewDelegate 72 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 73 | { 74 | NSString *defaultPassword = @"AprilBrother"; 75 | 76 | if (indexPath.row == 0) { 77 | // if the iBeacon supports Eddystone, you can use this method to change the broadcast to iBeacon and modify the parameters 78 | // if the iBeacon doesn't support Eddystone, you can use both the new and old method to modify parameters. 79 | // if you use new method to modify parameters for beacons not support Eddystone, you should set the boradcastType to ABBeaconBroadcastiBeacon, or you will get an error. 80 | // The default password is AprilBrother for AprilBeacon and 195660 for EEK iBeacon, 81 | // advInterval's unit is 100ms.if you set it to 5, then actually it is 500ms 82 | // if you just want to modify some of the parmaters, just set the no modified value to nil. as newpassword below. 83 | [self.beacon writeBeaconInfoByPassword:defaultPassword 84 | uuid:@"E2C56DB5-DFFB-48D2-B060-D0F5A71096E0" 85 | major:@(100) 86 | minor:@(101) 87 | txPower:@(ABTxPower0DBM) 88 | advInterval:@(5) 89 | measuredPower:@(-58) 90 | newpassword:nil 91 | broadcastType:ABBeaconBroadcastiBeacon 92 | withCompletion:^(NSError *error) { 93 | if (error == nil) { 94 | NSLog(@"修改成功"); 95 | } else { 96 | NSLog(@"修改失败%@", error); 97 | } 98 | }]; 99 | } else if (indexPath.row == 1) { 100 | [self.beacon writeEddyStoneUidAndReset:@"E2C56DB5-DFFB-48D2-B060-D0F5A71096E0" 101 | broadcastType:ABBeaconBroadcastEddystoneUid 102 | password:defaultPassword 103 | txPower:nil 104 | advInterval:@(5) 105 | newpassword:nil 106 | completion:^(NSError *error) { 107 | if (error == nil) { 108 | NSLog(@"修改成功"); 109 | } else { 110 | NSLog(@"修改失败%@", error); 111 | } 112 | }]; 113 | 114 | } else { 115 | [self.beacon writeEddyStoneURLAndReset:@"http://apbrother.com" 116 | broadcastType:ABBeaconBroadcastEddystoneURL 117 | password:defaultPassword 118 | txPower:ABTxPower0DBM 119 | advInterval:@(5) 120 | newpassword:nil 121 | completion:^(NSError *error) { 122 | if (error == nil) { 123 | NSLog(@"修改成功"); 124 | } else { 125 | NSLog(@"修改失败%@", error); 126 | } 127 | }]; 128 | } 129 | } 130 | 131 | @end 132 | -------------------------------------------------------------------------------- /AprilBeaconDemo/AprilBeaconDemo/ABNotificationViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ABNotificationViewController.h 3 | // TestSDKPod 4 | // 5 | // Created by liaojinhua on 14-5-8. 6 | // Copyright (c) 2014年 AprilBrother. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AprilBeaconSDK.h" 11 | 12 | @interface ABNotificationViewController : UIViewController 13 | 14 | @property (nonatomic, strong) ABBeacon *beacon; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /AprilBeaconDemo/AprilBeaconDemo/ABNotificationViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ABNotificationViewController.m 3 | // TestSDKPod 4 | // 5 | // Created by liaojinhua on 14-5-8. 6 | // Copyright (c) 2014年 AprilBrother. All rights reserved. 7 | // 8 | 9 | #import "ABNotificationViewController.h" 10 | 11 | @interface ABNotificationViewController () 12 | 13 | @property (nonatomic, strong) ABBeaconManager *beaconManager; 14 | @property (weak, nonatomic) IBOutlet UISwitch *enterSwitch; 15 | @property (weak, nonatomic) IBOutlet UISwitch *exitSwitch; 16 | 17 | @property (nonatomic, strong) ABBeaconRegion *region; 18 | 19 | @end 20 | 21 | @implementation ABNotificationViewController 22 | 23 | - (void)viewDidLoad 24 | { 25 | [super viewDidLoad]; 26 | // Do any additional setup after loading the view. 27 | 28 | self.beaconManager = [[ABBeaconManager alloc] init]; 29 | _beaconManager.delegate = self; 30 | 31 | [self startMonitoringForRegion]; 32 | } 33 | 34 | - (void)didReceiveMemoryWarning 35 | { 36 | [super didReceiveMemoryWarning]; 37 | // Dispose of any resources that can be recreated. 38 | } 39 | 40 | - (void)startMonitoringForRegion 41 | { 42 | if (!_region) { 43 | self.region = [[ABBeaconRegion alloc] initWithProximityUUID:_beacon.proximityUUID identifier:_beacon.proximityUUID.UUIDString]; 44 | } else { 45 | [_beaconManager stopMonitoringForRegion:self.region]; 46 | } 47 | self.region.notifyOnEntry = _enterSwitch.on; 48 | self.region.notifyOnExit = _exitSwitch.on; 49 | self.region.notifyEntryStateOnDisplay = YES; 50 | [_beaconManager startMonitoringForRegion:self.region]; 51 | } 52 | 53 | - (IBAction)enterSwitchChanaged:(UISwitch *)sender 54 | { 55 | [self startMonitoringForRegion]; 56 | } 57 | 58 | - (IBAction)exitSwitchChanged:(UISwitch *)sender 59 | { 60 | [self startMonitoringForRegion]; 61 | } 62 | 63 | @end 64 | -------------------------------------------------------------------------------- /AprilBeaconDemo/AprilBeaconDemo/ABSelectDeviceViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ABSelectDeviceViewController.h 3 | // TestSDKPod 4 | // 5 | // Created by liaojinhua on 14-5-8. 6 | // Copyright (c) 2014年 AprilBrother. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AprilBeaconSDK.h" 11 | 12 | @interface ABSelectDeviceViewController : UITableViewController 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /AprilBeaconDemo/AprilBeaconDemo/ABSelectDeviceViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ABSelectDeviceViewController.m 3 | // TestSDKPod 4 | // 5 | // Created by liaojinhua on 14-5-8. 6 | // Copyright (c) 2014年 AprilBrother. All rights reserved. 7 | // 8 | 9 | #import "ABSelectDeviceViewController.h" 10 | #import "ABTransmitters.h" 11 | #import "ABNotificationViewController.h" 12 | 13 | @interface ABSelectDeviceViewController () 14 | 15 | @property (nonatomic, strong) ABBeaconManager *beaconManager; 16 | @property (nonatomic, strong) NSMutableDictionary *tableData; 17 | 18 | @end 19 | 20 | @implementation ABSelectDeviceViewController 21 | 22 | - (void)viewDidLoad 23 | { 24 | [super viewDidLoad]; 25 | // Do any additional setup after loading the view, typically from a nib. 26 | 27 | self.beaconManager = [[ABBeaconManager alloc] init]; 28 | self.beaconManager.delegate = self; 29 | 30 | _tableData = [NSMutableDictionary dictionary]; 31 | 32 | self.refreshControl = [[UIRefreshControl alloc] init]; 33 | [self.refreshControl addTarget:self 34 | action:@selector(startRangeBeacons) 35 | forControlEvents:UIControlEventValueChanged]; 36 | } 37 | 38 | - (void)viewWillAppear:(BOOL)animated 39 | { 40 | [super viewWillAppear:animated]; 41 | [self startRangeBeacons]; 42 | } 43 | 44 | - (void)viewWillDisappear:(BOOL)animated 45 | { 46 | [super viewWillDisappear:animated]; 47 | [self stopRangeBeacons]; 48 | } 49 | 50 | - (void)didReceiveMemoryWarning 51 | { 52 | [super didReceiveMemoryWarning]; 53 | // Dispose of any resources that can be recreated. 54 | } 55 | 56 | #pragma mark - segue 57 | 58 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 59 | { 60 | if ([segue.identifier isEqualToString:@"notificationDemo"]) { 61 | NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow]; 62 | ABBeacon *beacon = [_tableData allValues][indexPath.section][indexPath.row]; 63 | 64 | ABNotificationViewController *view = segue.destinationViewController; 65 | view.beacon = beacon; 66 | } 67 | } 68 | 69 | #pragma mark - Table view data source 70 | 71 | 72 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 73 | { 74 | return [[_tableData allValues][section] count]; 75 | } 76 | 77 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 78 | { 79 | return _tableData.count; 80 | } 81 | 82 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 83 | { 84 | ABBeacon *beacon = [_tableData allValues][indexPath.section][indexPath.row]; 85 | 86 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"beaconCell"]; 87 | 88 | cell.textLabel.text = [beacon.proximityUUID UUIDString]; 89 | 90 | NSString *proximity; 91 | switch (beacon.proximity) { 92 | case CLProximityFar: 93 | proximity = @"Far"; 94 | break; 95 | case CLProximityImmediate: 96 | proximity = @"Immediate"; 97 | break; 98 | case CLProximityNear: 99 | proximity = @"Near"; 100 | break; 101 | default: 102 | proximity = @"Unknown"; 103 | break; 104 | } 105 | cell.detailTextLabel.text = [NSString stringWithFormat:@"Major: %@, Minor: %@, Acc: %.2fm, proximity=%@", beacon.major, beacon.minor, [beacon.distance floatValue], proximity]; 106 | 107 | return cell; 108 | } 109 | 110 | #pragma mark - ABBeaconManagerDelegate 111 | - (void)beaconManager:(ABBeaconManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(ABBeaconRegion *)region 112 | { 113 | [self.refreshControl endRefreshing]; 114 | [_tableData removeObjectForKey:region]; 115 | [_tableData setObject:beacons forKey:region]; 116 | [self.tableView reloadData]; 117 | } 118 | 119 | - (void)beaconManager:(ABBeaconManager *)manager rangingBeaconsDidFailForRegion:(ABBeaconRegion *)region withError:(NSError *)error 120 | { 121 | [self.refreshControl endRefreshing]; 122 | [_tableData removeObjectForKey:region]; 123 | [self.tableView reloadData]; 124 | } 125 | 126 | #pragma mark - Custom methods 127 | 128 | - (void)startRangeBeacons 129 | { 130 | [self stopRangeBeacons]; 131 | 132 | ABTransmitters *tran = [ABTransmitters sharedTransmitters]; 133 | [[tran transmitters] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 134 | NSUUID *proximityUUID = [[NSUUID alloc] initWithUUIDString:obj[@"uuid"]]; 135 | NSString *regionIdentifier = obj[@"uuid"]; 136 | 137 | ABBeaconRegion *beaconRegion; 138 | beaconRegion = [[ABBeaconRegion alloc] initWithProximityUUID:proximityUUID 139 | identifier:regionIdentifier]; 140 | beaconRegion.notifyOnEntry = YES; 141 | beaconRegion.notifyOnExit = YES; 142 | beaconRegion.notifyEntryStateOnDisplay = YES; 143 | [_beaconManager startRangingBeaconsInRegion:beaconRegion]; 144 | }]; 145 | } 146 | 147 | - (void)stopRangeBeacons 148 | { 149 | ABTransmitters *tran = [ABTransmitters sharedTransmitters]; 150 | [[tran transmitters] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 151 | NSUUID *proximityUUID = [[NSUUID alloc] initWithUUIDString:obj[@"uuid"]]; 152 | NSString *regionIdentifier = obj[@"uuid"]; 153 | 154 | ABBeaconRegion *beaconRegion; 155 | beaconRegion = [[ABBeaconRegion alloc] initWithProximityUUID:proximityUUID 156 | identifier:regionIdentifier]; 157 | [_beaconManager stopRangingBeaconsInRegion:beaconRegion]; 158 | }]; 159 | 160 | } 161 | @end 162 | -------------------------------------------------------------------------------- /AprilBeaconDemo/AprilBeaconDemo/ABSensorListViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ABSensorListViewController.h 3 | // AprilBeaconDemo 4 | // 5 | // Created by liaojinhua on 14-8-15. 6 | // Copyright (c) 2014年 AprilBrother. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ABSensorListViewController : UITableViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /AprilBeaconDemo/AprilBeaconDemo/ABSensorListViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ABSensorListViewController.m 3 | // AprilBeaconDemo 4 | // 5 | // Created by liaojinhua on 14-8-15. 6 | // Copyright (c) 2014年 AprilBrother. All rights reserved. 7 | // 8 | 9 | #import "ABSensorListViewController.h" 10 | #import 11 | #import "ABSensorViewController.h" 12 | 13 | @interface ABSensorListViewController () 14 | 15 | @property (nonatomic, strong) ABBluetoothManager *beaconManager; 16 | @property (nonatomic, strong) NSMutableArray *tableData; 17 | 18 | @end 19 | 20 | @implementation ABSensorListViewController 21 | 22 | - (void)viewDidLoad 23 | { 24 | [super viewDidLoad]; 25 | 26 | self.beaconManager = [[ABBluetoothManager alloc] init]; 27 | self.beaconManager.delegate = self; 28 | 29 | _tableData = [NSMutableArray array]; 30 | 31 | self.refreshControl = [[UIRefreshControl alloc] init]; 32 | [self.refreshControl addTarget:self 33 | action:@selector(startRangeBeacons) 34 | forControlEvents:UIControlEventValueChanged]; 35 | } 36 | 37 | - (void)viewWillAppear:(BOOL)animated 38 | { 39 | [super viewWillAppear:animated]; 40 | [self startRangeBeacons]; 41 | } 42 | 43 | - (void)viewWillDisappear:(BOOL)animated 44 | { 45 | [super viewWillDisappear:animated]; 46 | [self stopRangeBeacons]; 47 | } 48 | 49 | - (void)didReceiveMemoryWarning 50 | { 51 | [super didReceiveMemoryWarning]; 52 | // Dispose of any resources that can be recreated. 53 | } 54 | 55 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 56 | { 57 | if ([segue.identifier isEqualToString:@"ViewSensorSegue"]) { 58 | ABSensorViewController *vc = segue.destinationViewController; 59 | vc.sensor = sender; 60 | } 61 | } 62 | 63 | #pragma mark - Table view data source 64 | 65 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 66 | { 67 | return [_tableData count]; 68 | } 69 | 70 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 71 | { 72 | ABBeacon *beacon = _tableData[indexPath.row]; 73 | CBPeripheral *peripheral = beacon.peripheral; 74 | 75 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"beaconCell"]; 76 | 77 | cell.textLabel.text = peripheral.name; 78 | cell.detailTextLabel.text = [peripheral.identifier UUIDString]; 79 | 80 | return cell; 81 | } 82 | 83 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 84 | { 85 | [self performSegueWithIdentifier:@"ViewSensorSegue" sender:_tableData[indexPath.row]]; 86 | } 87 | 88 | 89 | #pragma mark - ABBeaconManagerDelegate 90 | - (void)beaconManager:(ABBeaconManager *)manager didDiscoverBeacons:(NSArray *)beacons { 91 | [self.refreshControl endRefreshing]; 92 | [_tableData removeAllObjects]; 93 | [beacons enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 94 | if ([obj isKindOfClass:[ABSensor class]]) { 95 | [_tableData addObject:obj]; 96 | } 97 | }]; 98 | [self.tableView reloadData]; 99 | } 100 | 101 | #pragma mark - Custom methods 102 | 103 | - (void)startRangeBeacons 104 | { 105 | [self stopRangeBeacons]; 106 | [_beaconManager startAprilBeaconsDiscovery]; 107 | } 108 | 109 | - (void)stopRangeBeacons 110 | { 111 | [_beaconManager stopAprilBeaconDiscovery]; 112 | } 113 | @end 114 | -------------------------------------------------------------------------------- /AprilBeaconDemo/AprilBeaconDemo/ABSensorViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ABSensorViewController.h 3 | // Examples 4 | // 5 | // Created by liaojinhua on 14-7-3. 6 | // Copyright (c) 2014年 li shuai. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @import GLKit; 13 | @import OpenGLES.ES2; 14 | 15 | @interface ABSensorViewController : GLKViewController 16 | 17 | @property (nonatomic, strong) ABSensor *sensor; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /AprilBeaconDemo/AprilBeaconDemo/ABSensorViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ABSensorViewController.m 3 | // Examples 4 | // 5 | // Created by liaojinhua on 14-7-3. 6 | // Copyright (c) 2014年 li shuai. All rights reserved. 7 | // 8 | 9 | #import "ABSensorViewController.h" 10 | 11 | typedef struct { 12 | float Position[3]; 13 | float Color[4]; 14 | float TexCoord[2]; 15 | } Vertex; 16 | 17 | const Vertex Vertices[] = { 18 | // Front 19 | {{1, -1, 1}, {1, 0, 0, 1}, {1, 0}}, 20 | {{1, 1, 1}, {1, 0, 0, 1}, {1, 1}}, 21 | {{-1, 1, 1}, {1, 0, 0, 1}, {0, 1}}, 22 | {{-1, -1, 1}, {1, 0, 0, 1}, {0, 0}}, 23 | // Back 24 | {{1, 1, -1}, {0, 1, 0, 1}, {0, 1}}, 25 | {{-1, -1, -1}, {0, 1, 0, 1}, {1, 0}}, 26 | {{1, -1, -1}, {0, 1, 0, 1}, {0, 0}}, 27 | {{-1, 1, -1}, {0, 1, 0, 1}, {1, 1}}, 28 | // Left 29 | {{-1, -1, 1}, {0, 0, 1, 1}, {1, 0}}, 30 | {{-1, 1, 1}, {0, 0, 1, 1}, {1, 1}}, 31 | {{-1, 1, -1}, {0, 0, 1, 1}, {0, 1}}, 32 | {{-1, -1, -1}, {0, 0, 1, 1}, {0, 0}}, 33 | // Right 34 | {{1, -1, -1}, {0.5, 0, 0.5, 1}, {1, 0}}, 35 | {{1, 1, -1}, {0.5, 0, 0.5, 1}, {1, 1}}, 36 | {{1, 1, 1}, {0.5, 0, 0.5, 1}, {0, 1}}, 37 | {{1, -1, 1}, {0.5, 0, 0.5, 1}, {0, 0}}, 38 | // Top 39 | {{1, 1, 1}, {0.5, 0.5, 0, 1}, {1, 0}}, 40 | {{1, 1, -1}, {0.5, 0.5, 0, 1}, {1, 1}}, 41 | {{-1, 1, -1}, {0.5, 0.5, 0, 1}, {0, 1}}, 42 | {{-1, 1, 1}, {0.5, 0.5, 0, 1}, {0, 0}}, 43 | // Bottom 44 | {{1, -1, -1}, {0, 0.5, 0.5, 1}, {1, 0}}, 45 | {{1, -1, 1}, {0, 0.5, 0.5, 1}, {1, 1}}, 46 | {{-1, -1, 1}, {0, 0.5, 0.5, 1}, {0, 1}}, 47 | {{-1, -1, -1}, {0, 0.5, 0.5, 1}, {0, 0}} 48 | }; 49 | 50 | const GLubyte Indices[] = { 51 | // Front 52 | 0, 1, 2, 53 | 2, 3, 0, 54 | // Back 55 | 4, 6, 5, 56 | 4, 5, 7, 57 | // Left 58 | 8, 9, 10, 59 | 10, 11, 8, 60 | // Right 61 | 12, 13, 14, 62 | 14, 15, 12, 63 | // Top 64 | 16, 17, 18, 65 | 18, 19, 16, 66 | // Bottom 67 | 20, 21, 22, 68 | 22, 23, 20 69 | }; 70 | 71 | 72 | 73 | 74 | @interface ABSensorViewController () 75 | { 76 | // MBProgressHUD *_mbp; 77 | 78 | GLuint _vertexBuffer; 79 | GLuint _indexBuffer; 80 | GLuint _vertexArray; 81 | float _rotation; 82 | GLKMatrix4 _rotMatrix; 83 | GLKVector3 _anchor_position; 84 | GLKVector3 _current_position; 85 | GLKQuaternion _quatStart; 86 | GLKQuaternion _quat; 87 | 88 | BOOL _slerping; 89 | float _slerpCur; 90 | float _slerpMax; 91 | GLKQuaternion _slerpStart; 92 | GLKQuaternion _slerpEnd; 93 | } 94 | 95 | 96 | @property (nonatomic, strong) CBCharacteristic *accCharacteristic; 97 | @property (nonatomic, strong) CBCharacteristic *accDataCharacteristic; 98 | @property (nonatomic, strong) CBCharacteristic *lightCharacteristic; 99 | @property (nonatomic, strong) CBCharacteristic *lightDataCharacteristic; 100 | 101 | @property (nonatomic) BOOL dataUpdated; 102 | 103 | @property (nonatomic) float angleAccX; 104 | @property (nonatomic) float angleAccY; 105 | @property (nonatomic) float angleAccZ; 106 | 107 | @property (nonatomic) double light; 108 | 109 | @property (strong, nonatomic) EAGLContext *context; 110 | @property (strong, nonatomic) GLKBaseEffect *effect; 111 | 112 | @property (weak, nonatomic) IBOutlet UILabel *xLabel; 113 | @property (weak, nonatomic) IBOutlet UILabel *yLabel; 114 | @property (weak, nonatomic) IBOutlet UILabel *zLabel; 115 | @property (weak, nonatomic) IBOutlet UILabel *lightLabel; 116 | @property (weak, nonatomic) IBOutlet UISwitch *accSwitch; 117 | @property (weak, nonatomic) IBOutlet UISwitch *lightSwitch; 118 | 119 | @end 120 | 121 | @implementation ABSensorViewController 122 | 123 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 124 | { 125 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 126 | if (self) { 127 | // Custom initialization 128 | } 129 | return self; 130 | } 131 | 132 | - (void)viewDidLoad 133 | { 134 | [super viewDidLoad]; 135 | // Do any additional setup after loading the view. 136 | 137 | self.title = self.sensor.peripheral.name; 138 | [self initGLData]; 139 | [self setupGL]; 140 | } 141 | 142 | - (void)viewWillAppear:(BOOL)animated 143 | { 144 | [super viewWillAppear:animated]; 145 | self.sensor.delegate = self; 146 | [self connectToPeripheral]; 147 | __weak ABSensorViewController *wSelf = self; 148 | [self.sensor setAccValueChangedBlock:^(ABAcceleration acceleration) { 149 | CGFloat Ax = acceleration.x; 150 | CGFloat Ay = acceleration.y; 151 | CGFloat Az = acceleration.z; 152 | wSelf.angleAccX = atan(Ax/sqrt(Az*Az+Ay*Ay))*180/3.14; 153 | wSelf.angleAccY = atan(Ay/sqrt(Ax*Ax+Az*Az))*180/3.14; 154 | wSelf.angleAccZ = atan(Az/sqrt(Ax*Ax+Ay*Ay))*180/3.14; 155 | wSelf.dataUpdated = YES; 156 | }]; 157 | 158 | [self.sensor setLightValueChangedBlock:^(double light) { 159 | wSelf.light = light; 160 | wSelf.dataUpdated = YES; 161 | }]; 162 | } 163 | 164 | - (void)viewWillDisappear:(BOOL)animated 165 | { 166 | [super viewWillDisappear:animated]; 167 | [self.sensor disconnectBeacon]; 168 | [self.sensor setAccValueChangedBlock:nil]; 169 | [self.sensor setLightValueChangedBlock:nil]; 170 | self.sensor.delegate = nil; 171 | } 172 | 173 | - (void)connectToPeripheral 174 | { 175 | [self.sensor connectToBeacon]; 176 | [self showProgress:@"Connecting Device"]; 177 | } 178 | 179 | - (void)didReceiveMemoryWarning 180 | { 181 | [super didReceiveMemoryWarning]; 182 | // Dispose of any resources that can be recreated. 183 | } 184 | - (IBAction)switchValueChanged:(UISwitch *)sender 185 | { 186 | UInt8 value = 0; 187 | if (sender.on) { 188 | value = 1; 189 | } 190 | if (sender == self.accSwitch) { 191 | [self.sensor setAccelerometerOn:value WithCompletion:nil]; 192 | } else { 193 | [self.sensor setLightSensorOn:value WithCompletion:nil]; 194 | } 195 | } 196 | 197 | - (void)showProgress:(NSString *)title 198 | { 199 | // _mbp = [[MBProgressHUD alloc] initWithView:self.view]; 200 | // _mbp.labelText = title; 201 | // [self.view addSubview:_mbp]; 202 | // [_mbp show:YES]; 203 | } 204 | 205 | - (void)hideProgress 206 | { 207 | // [_mbp removeFromSuperview]; 208 | } 209 | 210 | - (void)initGLData 211 | { 212 | self.angleAccX = 0.0; 213 | self.angleAccY = 0.0; 214 | self.angleAccZ = 0.0; 215 | 216 | self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; 217 | 218 | if (!self.context) { 219 | NSLog(@"Failed to create ES context"); 220 | } 221 | 222 | GLKView *view = (GLKView *)self.view; 223 | view.context = self.context; 224 | view.drawableMultisample = GLKViewDrawableMultisample4X; 225 | } 226 | 227 | - (void)setupGL { 228 | 229 | [EAGLContext setCurrentContext:self.context]; 230 | glEnable(GL_CULL_FACE); 231 | 232 | self.effect = [[GLKBaseEffect alloc] init]; 233 | 234 | NSDictionary * options = [NSDictionary dictionaryWithObjectsAndKeys: 235 | [NSNumber numberWithBool:YES], 236 | GLKTextureLoaderOriginBottomLeft, 237 | nil]; 238 | 239 | NSError * error; 240 | NSString *path = [[NSBundle mainBundle] pathForResource:@"tile_floor" ofType:@"png"]; 241 | GLKTextureInfo * info = [GLKTextureLoader textureWithContentsOfFile:path options:options error:&error]; 242 | if (info == nil) { 243 | NSLog(@"Error loading file: %@", [error localizedDescription]); 244 | } 245 | self.effect.texture2d0.name = info.name; 246 | self.effect.texture2d0.enabled = true; 247 | 248 | // New lines 249 | glGenVertexArraysOES(1, &_vertexArray); 250 | glBindVertexArrayOES(_vertexArray); 251 | 252 | // Old stuff 253 | glGenBuffers(1, &_vertexBuffer); 254 | glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); 255 | glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW); 256 | 257 | glGenBuffers(1, &_indexBuffer); 258 | glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer); 259 | glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Indices), Indices, GL_STATIC_DRAW); 260 | 261 | // New lines (were previously in draw) 262 | glEnableVertexAttribArray(GLKVertexAttribPosition); 263 | glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *) offsetof(Vertex, Position)); 264 | glEnableVertexAttribArray(GLKVertexAttribColor); 265 | glVertexAttribPointer(GLKVertexAttribColor, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *) offsetof(Vertex, Color)); 266 | glEnableVertexAttribArray(GLKVertexAttribTexCoord0); 267 | glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *) offsetof(Vertex, TexCoord)); 268 | 269 | // New line 270 | glBindVertexArrayOES(0); 271 | 272 | _rotMatrix = GLKMatrix4Identity; 273 | _quat = GLKQuaternionMake(0, 0, 0, 1); 274 | _quatStart = GLKQuaternionMake(0, 0, 0, 1); 275 | } 276 | 277 | - (void)tearDownGL { 278 | 279 | [EAGLContext setCurrentContext:self.context]; 280 | 281 | glDeleteBuffers(1, &_vertexBuffer); 282 | glDeleteBuffers(1, &_indexBuffer); 283 | 284 | self.effect = nil; 285 | 286 | } 287 | 288 | #pragma mark - GLKViewDelegate 289 | 290 | - (void)glkView:(GLKView *)view drawInRect:(CGRect)rect { 291 | 292 | glClearColor(200.0, 200.0, 200.0, 1.0); 293 | glClear(GL_COLOR_BUFFER_BIT); 294 | 295 | [self.effect prepareToDraw]; 296 | 297 | glBindVertexArrayOES(_vertexArray); 298 | glDrawElements(GL_TRIANGLES, sizeof(Indices)/sizeof(Indices[0]), GL_UNSIGNED_BYTE, 0); 299 | 300 | } 301 | 302 | #pragma mark - GLKViewControllerDelegate 303 | 304 | - (void)update { 305 | if(self.dataUpdated){ 306 | self.dataUpdated = false; 307 | self.xLabel.text = [NSString stringWithFormat:@"X:%.2f", self.angleAccX]; 308 | self.yLabel.text = [NSString stringWithFormat:@"Y:%.2f", self.angleAccY]; 309 | self.zLabel.text = [NSString stringWithFormat:@"Z:%.2f", self.angleAccZ]; 310 | self.lightLabel.text = [NSString stringWithFormat:@"Light:%.f", self.light]; 311 | } 312 | 313 | float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); 314 | GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 4.0f, 10.0f); 315 | self.effect.transform.projectionMatrix = projectionMatrix; 316 | 317 | if (_slerping) { 318 | 319 | _slerpCur += self.timeSinceLastUpdate; 320 | float slerpAmt = _slerpCur / _slerpMax; 321 | if (slerpAmt > 1.0) { 322 | slerpAmt = 1.0; 323 | _slerping = NO; 324 | } 325 | 326 | _quat = GLKQuaternionSlerp(_slerpStart, _slerpEnd, slerpAmt); 327 | } 328 | 329 | GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -6.0f); 330 | /* 331 | //modelViewMatrix = GLKMatrix4Multiply(modelViewMatrix, _rotMatrix); 332 | GLKMatrix4 rotation = GLKMatrix4MakeWithQuaternion(_quat); 333 | modelViewMatrix = GLKMatrix4Multiply(modelViewMatrix, rotation); 334 | */ 335 | //_rotation += 90 * self.timeSinceLastUpdate; 336 | modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, GLKMathDegreesToRadians(self.angleAccY), 1, 0, 0); 337 | modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, GLKMathDegreesToRadians(-self.angleAccX), 0, 1, 0); 338 | // modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, GLKMathDegreesToRadians(self.angleAccZ), 0, 0, 1); 339 | 340 | self.effect.transform.modelviewMatrix = modelViewMatrix; 341 | 342 | } 343 | 344 | - (GLKVector3) projectOntoSurface:(GLKVector3) touchPoint 345 | { 346 | float radius = self.view.bounds.size.width/3; 347 | GLKVector3 center = GLKVector3Make(self.view.bounds.size.width/2, self.view.bounds.size.height/2, 0); 348 | GLKVector3 P = GLKVector3Subtract(touchPoint, center); 349 | 350 | // Flip the y-axis because pixel coords increase toward the bottom. 351 | P = GLKVector3Make(P.x, P.y * -1, P.z); 352 | 353 | float radius2 = radius * radius; 354 | float length2 = P.x*P.x + P.y*P.y; 355 | 356 | if (length2 <= radius2) 357 | P.z = sqrt(radius2 - length2); 358 | else 359 | { 360 | /* 361 | P.x *= radius / sqrt(length2); 362 | P.y *= radius / sqrt(length2); 363 | P.z = 0; 364 | */ 365 | P.z = radius2 / (2.0 * sqrt(length2)); 366 | float length = sqrt(length2 + P.z * P.z); 367 | P = GLKVector3DivideScalar(P, length); 368 | } 369 | 370 | return GLKVector3Normalize(P); 371 | } 372 | 373 | - (void)computeIncremental { 374 | 375 | GLKVector3 axis = GLKVector3CrossProduct(_anchor_position, _current_position); 376 | float dot = GLKVector3DotProduct(_anchor_position, _current_position); 377 | float angle = acosf(dot); 378 | 379 | GLKQuaternion Q_rot = GLKQuaternionMakeWithAngleAndVector3Axis(angle * 2, axis); 380 | Q_rot = GLKQuaternionNormalize(Q_rot); 381 | 382 | // TODO: Do something with Q_rot... 383 | _quat = GLKQuaternionMultiply(Q_rot, _quatStart); 384 | } 385 | 386 | - (void)beaconConnectionDidSucceeded:(ABBeacon *)beacon 387 | { 388 | 389 | } 390 | 391 | - (void)beaconDidDisconnect:(ABBeacon *)beacon withError:(NSError *)error 392 | { 393 | UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSInternalInconsistencyException message:@"已断开连接,请重现尝试" delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil]; 394 | 395 | [alert show]; 396 | } 397 | 398 | - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex 399 | { 400 | [self.navigationController popViewControllerAnimated:YES]; 401 | } 402 | 403 | @end 404 | -------------------------------------------------------------------------------- /AprilBeaconDemo/AprilBeaconDemo/ABTransmitters.h: -------------------------------------------------------------------------------- 1 | // 2 | // ABTransmitters.h 3 | // AprilBeacon 4 | // 5 | // Created by yy on 14-1-26. 6 | // Copyright (c) 2014年 AprilBrother. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ABTransmitters : NSObject 12 | 13 | + (ABTransmitters *)sharedTransmitters; 14 | 15 | - (NSArray *)transmitters; 16 | - (NSArray *)historyUUIDs; 17 | - (void)addHistoryUUID:(NSString *)uuid; 18 | - (BOOL)addTransmitter:(NSDictionary *)transmitter; 19 | - (void)replaceAtIndex:(NSInteger)index withTransmitter:(NSDictionary *)transmitter; 20 | - (void)removeTransmitterAtIndex:(NSInteger)index; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /AprilBeaconDemo/AprilBeaconDemo/ABTransmitters.m: -------------------------------------------------------------------------------- 1 | // 2 | // ABTransmitters.m 3 | // AprilBeacon 4 | // 5 | // Created by yy on 14-1-26. 6 | // Copyright (c) 2014年 AprilBrother. All rights reserved. 7 | // 8 | 9 | #import "ABTransmitters.h" 10 | 11 | #define kTransmitterKey @"transmitters" 12 | #define kHistoryUUIDKey @"historyUUIDss" 13 | 14 | @implementation ABTransmitters 15 | 16 | #pragma mark - public 17 | 18 | + (ABTransmitters *)sharedTransmitters { 19 | static dispatch_once_t once; 20 | static id sharedInstance; 21 | 22 | dispatch_once(&once, ^{ 23 | sharedInstance = [self new]; 24 | }); 25 | 26 | return sharedInstance; 27 | } 28 | 29 | - (NSArray *)transmitters { 30 | NSArray *result = [[NSUserDefaults standardUserDefaults] arrayForKey:kTransmitterKey]; 31 | if(nil == result) { 32 | [self setupData]; 33 | result = [[NSUserDefaults standardUserDefaults] arrayForKey:kTransmitterKey]; 34 | } 35 | return result; 36 | } 37 | 38 | - (NSArray *)historyUUIDs { 39 | NSArray *result = [[NSUserDefaults standardUserDefaults] arrayForKey:kHistoryUUIDKey]; 40 | if(nil == result) { 41 | NSArray *transimitters = [self transmitters]; 42 | NSMutableArray *history = [NSMutableArray arrayWithCapacity:transimitters.count]; 43 | for (NSDictionary *data in transimitters) { 44 | if ([history indexOfObject:data[@"uuid"]] == NSNotFound) { 45 | [history addObject:data[@"uuid"]]; 46 | } 47 | } 48 | [[NSUserDefaults standardUserDefaults] setObject:history forKey:kHistoryUUIDKey]; 49 | result = history; 50 | } 51 | return result; 52 | } 53 | 54 | - (BOOL)addTransmitter:(NSDictionary *)transmitter { 55 | NSMutableArray *mutableResult = [[self transmitters] mutableCopy]; 56 | for (NSDictionary *trans in mutableResult) { 57 | if ([trans[@"uuid"] isEqualToString:transmitter[@"uuid"]]) { 58 | return NO; 59 | } 60 | } 61 | [mutableResult addObject:transmitter]; 62 | 63 | [[NSUserDefaults standardUserDefaults] setObject:mutableResult forKey:kTransmitterKey]; 64 | [[NSUserDefaults standardUserDefaults] synchronize]; 65 | return YES; 66 | } 67 | 68 | - (BOOL)isExist:(NSString *)uuid { 69 | NSMutableArray *mutableResult = [[self transmitters] mutableCopy]; 70 | for (NSDictionary *trans in mutableResult) { 71 | if ([trans[@"uuid"] isEqualToString:uuid]) { 72 | return YES; 73 | } 74 | } 75 | return NO; 76 | } 77 | 78 | - (void)replaceAtIndex:(NSInteger)index withTransmitter:(NSDictionary *)transmitter { 79 | NSMutableArray *mutableResult = [[self transmitters] mutableCopy]; 80 | [mutableResult replaceObjectAtIndex:index withObject:transmitter]; 81 | [[NSUserDefaults standardUserDefaults] setObject:mutableResult forKey:kTransmitterKey]; 82 | [[NSUserDefaults standardUserDefaults] synchronize]; 83 | } 84 | 85 | - (void)removeTransmitterAtIndex:(NSInteger)index { 86 | NSMutableArray *mutableResult = [[self transmitters] mutableCopy]; 87 | if (index < mutableResult.count) { 88 | [mutableResult removeObjectAtIndex:index]; 89 | [[NSUserDefaults standardUserDefaults] setObject:mutableResult forKey:kTransmitterKey]; 90 | [[NSUserDefaults standardUserDefaults] synchronize]; 91 | } 92 | } 93 | 94 | - (void)addHistoryUUID:(NSString *)uuid 95 | { 96 | if (!uuid || uuid.length == 0) { 97 | return ; 98 | } 99 | NSMutableArray *result = [NSMutableArray arrayWithArray:[[NSUserDefaults standardUserDefaults] arrayForKey:kHistoryUUIDKey]]; 100 | if ([result indexOfObject:uuid] == NSNotFound) { 101 | [result addObject:uuid]; 102 | } 103 | if (result.count > 20) { 104 | [result removeObjectAtIndex:0]; 105 | } 106 | [[NSUserDefaults standardUserDefaults] setObject:result forKey:kHistoryUUIDKey]; 107 | } 108 | 109 | #pragma mark - private 110 | 111 | - (void)setupData { 112 | NSArray *data = @[ 113 | @{ 114 | @"name" : @"AprilBeacon", 115 | @"uuid" : @"E2C56DB5-DFFB-48D2-B060-D0F5A71096E0", 116 | @"major" : @0, 117 | @"minor" : @0, 118 | @"power" : @-59 119 | }, 120 | 121 | @{ 122 | @"name" : @"Apple AirLocate", 123 | @"uuid" : @"5A4BCFCE-174E-4BAC-A814-092E77F6B7E5", 124 | @"major" : @0, 125 | @"minor" : @0, 126 | @"power" : @-59 127 | }, 128 | @{ 129 | @"name" : @"Apple AirLocate2", 130 | @"uuid" : @"74278BDA-B644-4520-8F0C-720EAF059935", 131 | @"major" : @0, 132 | @"minor" : @0, 133 | @"power" : @-59 134 | }, 135 | @{ 136 | @"name" : @"ESTimote", 137 | @"uuid" : @"B9407F30-F5F8-466E-AFF9-25556B57FE6D", 138 | @"major" : @0, 139 | @"minor" : @0, 140 | @"power" : @-59 141 | }, 142 | 143 | @{ 144 | @"name" : @"WeixinForBeacon", 145 | @"uuid" : @"FDA50693-A4E2-4FB1-AFCF-C6EB07647825", 146 | @"major" : @0, 147 | @"minor" : @0, 148 | @"power" : @-59 149 | }, 150 | @{ 151 | @"name" : @"EEK Beacon", 152 | @"uuid" : @"B5B182C7-EAB1-4988-AA99-B5C1517008D9", 153 | @"major" : @0, 154 | @"minor" : @0, 155 | @"power" : @-59 156 | } 157 | ]; 158 | [[NSUserDefaults standardUserDefaults] setObject:data forKey:kTransmitterKey]; 159 | [[NSUserDefaults standardUserDefaults] synchronize]; 160 | } 161 | 162 | @end 163 | -------------------------------------------------------------------------------- /AprilBeaconDemo/AprilBeaconDemo/ABUUIDTextField.h: -------------------------------------------------------------------------------- 1 | // 2 | // ABUUIDTextField.h 3 | // AprilBeacon 4 | // 5 | // Created by liaojinhua on 14-8-8. 6 | // Copyright (c) 2014年 AprilBrother. All rights reserved. 7 | // 8 | 9 | #import "JVFloatLabeledTextField.h" 10 | 11 | @interface ABUUIDTextField : JVFloatLabeledTextField 12 | 13 | - (void)hideFloatLabel; 14 | - (void)hideLeftButton; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /AprilBeaconDemo/AprilBeaconDemo/ABUUIDTextField.m: -------------------------------------------------------------------------------- 1 | // 2 | // ABUUIDTextField.m 3 | // AprilBeacon 4 | // 5 | // Created by liaojinhua on 14-8-8. 6 | // Copyright (c) 2014年 AprilBrother. All rights reserved. 7 | // 8 | 9 | #import "ABUUIDTextField.h" 10 | #import "ABTransmitters.h" 11 | 12 | @interface ABUUIDTextField () 13 | 14 | @property (nonatomic, strong) UIToolbar *toolbar; 15 | @property (nonatomic, strong) UIPickerView *pickerView; 16 | @property (nonatomic, strong) UIBarButtonItem *leftButton; 17 | @property (nonatomic, strong) UIBarButtonItem *fixedBarButton; 18 | @property (nonatomic, strong) UIBarButtonItem *rightButton; 19 | 20 | @property (nonatomic, strong) NSArray *uuidArray; 21 | 22 | @end 23 | 24 | @implementation ABUUIDTextField 25 | 26 | - (instancetype)init 27 | { 28 | if (self = [super init]) { 29 | [self addAssistantView]; 30 | } 31 | return self; 32 | } 33 | 34 | - (void)awakeFromNib 35 | { 36 | [self addAssistantView]; 37 | [self loadData]; 38 | } 39 | 40 | - (void)hideFloatLabel 41 | { 42 | self.floatingLabel.font = [UIFont systemFontOfSize:0]; 43 | self.clearButtonMode = UITextFieldViewModeWhileEditing; 44 | } 45 | 46 | - (void)hideLeftButton 47 | { 48 | [self.toolbar setItems:@[self.fixedBarButton, self.rightButton]]; 49 | } 50 | 51 | - (void)addAssistantView 52 | { 53 | if (self.toolbar) { 54 | return; 55 | } 56 | self.autocapitalizationType = UITextAutocapitalizationTypeAllCharacters; 57 | self.clearButtonMode = UITextFieldViewModeWhileEditing; 58 | self.toolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)]; 59 | self.toolbar.translucent = NO; 60 | self.leftButton = [[UIBarButtonItem alloc] initWithTitle:@"生成" style:UIBarButtonItemStylePlain target:self action:@selector(generate:)]; 61 | self.fixedBarButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil]; 62 | 63 | self.rightButton = [[UIBarButtonItem alloc] initWithTitle:@"选择 UUID" style:UIBarButtonItemStylePlain target:self action:@selector(selectUUID:)]; 64 | [self.toolbar setItems:@[self.leftButton, self.fixedBarButton, self.rightButton]]; 65 | self.inputAccessoryView = self.toolbar; 66 | 67 | self.pickerView = [[UIPickerView alloc] initWithFrame:CGRectMake(0, 0, 320, 216)]; 68 | self.pickerView.delegate = self; 69 | self.pickerView.dataSource = self; 70 | } 71 | - (void)loadData 72 | { 73 | _uuidArray = [[ABTransmitters sharedTransmitters] historyUUIDs]; 74 | } 75 | 76 | - (void)generate:(id)sender 77 | { 78 | if (self.inputView) { 79 | self.inputView = nil; 80 | self.leftButton.title = @"生成"; 81 | } else { 82 | self.text = [[NSUUID UUID] UUIDString]; 83 | } 84 | [UIView animateWithDuration:1.0f animations:^{ 85 | [self reloadInputViews]; 86 | [self becomeFirstResponder]; 87 | }]; 88 | } 89 | 90 | - (void)selectUUID:(id)sender 91 | { 92 | [self endEditing:YES]; 93 | 94 | if (self.inputView == self.pickerView) { 95 | self.inputView = nil; 96 | self.rightButton.title = @"选择 UUID"; 97 | self.leftButton.title = @"生成"; 98 | [UIView animateWithDuration:1.0f animations:^{ 99 | [self reloadInputViews]; 100 | [self becomeFirstResponder]; 101 | }]; 102 | return; 103 | } 104 | 105 | if (self.toolbar.items.count == 3) { 106 | self.leftButton.title = @"返回"; 107 | } else { 108 | self.rightButton.title = @"返回"; 109 | } 110 | 111 | self.inputView = self.pickerView; 112 | if (_uuidArray.count > 0) { 113 | self.text = [_uuidArray firstObject]; 114 | } 115 | [self becomeFirstResponder]; 116 | } 117 | 118 | - (NSString *)text 119 | { 120 | return [[super text] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; 121 | } 122 | 123 | 124 | #pragma mark - UIPickerViewDelegate 125 | - (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component 126 | { 127 | if (row < _uuidArray.count) { 128 | self.text = _uuidArray[row]; 129 | } 130 | } 131 | 132 | #pragma mark - UIPickerViewDataSource 133 | 134 | - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView 135 | { 136 | return 1; 137 | } 138 | 139 | - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component 140 | { 141 | return _uuidArray.count; 142 | } 143 | 144 | - (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component 145 | { 146 | return _uuidArray[row]; 147 | } 148 | 149 | 150 | @end 151 | -------------------------------------------------------------------------------- /AprilBeaconDemo/AprilBeaconDemo/AprilBeaconDemo-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 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 | NSLocationAlwaysUsageDescription 28 | Use location to detect iBeacons 29 | NSLocationWhenInUseUsageDescription 30 | Use location to detect iBeacons 31 | UILaunchStoryboardName 32 | LaunchScreen 33 | UIMainStoryboardFile 34 | Main 35 | UIRequiredDeviceCapabilities 36 | 37 | armv7 38 | 39 | UISupportedInterfaceOrientations 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationLandscapeLeft 43 | UIInterfaceOrientationLandscapeRight 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /AprilBeaconDemo/AprilBeaconDemo/AprilBeaconDemo-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 | -------------------------------------------------------------------------------- /AprilBeaconDemo/AprilBeaconDemo/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 | } -------------------------------------------------------------------------------- /AprilBeaconDemo/AprilBeaconDemo/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 | } -------------------------------------------------------------------------------- /AprilBeaconDemo/AprilBeaconDemo/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /AprilBeaconDemo/AprilBeaconDemo/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /AprilBeaconDemo/AprilBeaconDemo/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // AprilBeaconDemo 4 | // 5 | // Created by liaojinhua on 14-5-7. 6 | // Copyright (c) 2014年 AprilBrother. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "ABAppDelegate.h" 12 | 13 | int main(int argc, char * argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([ABAppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /AprilBeaconDemo/AprilBeaconDemoTests/AprilBeaconDemoTests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /AprilBeaconDemo/AprilBeaconDemoTests/AprilBeaconDemoTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // AprilBeaconDemoTests.m 3 | // AprilBeaconDemoTests 4 | // 5 | // Created by liaojinhua on 14-5-7. 6 | // Copyright (c) 2014年 AprilBrother. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AprilBeaconDemoTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation AprilBeaconDemoTests 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 | -------------------------------------------------------------------------------- /AprilBeaconDemo/AprilBeaconDemoTests/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /AprilBeaconDemo/JVFloatLabeledTextField/JVFloatLabeledTextField.h: -------------------------------------------------------------------------------- 1 | // 2 | // JVFloatLabeledTextField.h 3 | // JVFloatLabeledTextField 4 | // 5 | // The MIT License (MIT) 6 | // 7 | // Copyright (c) 2013 Jared Verdi 8 | // Original Concept by Matt D. Smith 9 | // http://dribbble.com/shots/1254439--GIF-Mobile-Form-Interaction?list=users 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy of 12 | // this software and associated documentation files (the "Software"), to deal in 13 | // the Software without restriction, including without limitation the rights to 14 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 15 | // the Software, and to permit persons to whom the Software is furnished to do so, 16 | // subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in all 19 | // copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 23 | // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 24 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 25 | // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 26 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 27 | 28 | 29 | #import 30 | 31 | @interface JVFloatLabeledTextField : UITextField 32 | 33 | @property (nonatomic, strong, readonly) UILabel * floatingLabel; 34 | @property (nonatomic, strong) NSNumber * floatingLabelYPadding UI_APPEARANCE_SELECTOR; 35 | @property (nonatomic, strong) UIFont * floatingLabelFont UI_APPEARANCE_SELECTOR; 36 | @property (nonatomic, strong) UIColor * floatingLabelTextColor UI_APPEARANCE_SELECTOR; 37 | @property (nonatomic, strong) UIColor * floatingLabelActiveTextColor UI_APPEARANCE_SELECTOR; // tint color is used by default if not provided 38 | @property (nonatomic, assign) NSInteger animateEvenIfNotFirstResponder UI_APPEARANCE_SELECTOR; // Can't use BOOL for UI_APPEARANCE. Non-zero == YES 39 | @property (nonatomic, assign) NSTimeInterval floatingLabelShowAnimationDuration; 40 | @property (nonatomic, assign) NSTimeInterval floatingLabelHideAnimationDuration; 41 | 42 | /** 43 | * Sets the placeholder and the floating title 44 | * 45 | * @param placeholder The string that is displayed when there is no other text in the text field. 46 | * @param floatingTitle The string that is displayed above the text field when it's not empty. 47 | */ 48 | - (void)setPlaceholder:(NSString *)placeholder floatingTitle:(NSString *)floatingTitle; 49 | 50 | @end 51 | -------------------------------------------------------------------------------- /AprilBeaconDemo/JVFloatLabeledTextField/JVFloatLabeledTextField.m: -------------------------------------------------------------------------------- 1 | // 2 | // JVFloatLabeledTextField.m 3 | // JVFloatLabeledTextField 4 | // 5 | // The MIT License (MIT) 6 | // 7 | // Copyright (c) 2013 Jared Verdi 8 | // Original Concept by Matt D. Smith 9 | // http://dribbble.com/shots/1254439--GIF-Mobile-Form-Interaction?list=users 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy of 12 | // this software and associated documentation files (the "Software"), to deal in 13 | // the Software without restriction, including without limitation the rights to 14 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 15 | // the Software, and to permit persons to whom the Software is furnished to do so, 16 | // subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in all 19 | // copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 23 | // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 24 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 25 | // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 26 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 27 | 28 | #import "JVFloatLabeledTextField.h" 29 | #import "NSString+TextDirectionality.h" 30 | 31 | #define kFloatingLabelShowAnimationDuration 0.3f 32 | #define kFloatingLabelHideAnimationDuration 0.3f 33 | 34 | @implementation JVFloatLabeledTextField 35 | 36 | - (id)initWithFrame:(CGRect)frame 37 | { 38 | self = [super initWithFrame:frame]; 39 | if (self) { 40 | [self commonInit]; 41 | } 42 | return self; 43 | } 44 | 45 | - (id)initWithCoder:(NSCoder *)aDecoder 46 | { 47 | self = [super initWithCoder:aDecoder]; 48 | if (self) { 49 | [self commonInit]; 50 | 51 | // force setter to be called on a placeholder defined in a NIB/Storyboard 52 | if (self.placeholder) { 53 | self.placeholder = self.placeholder; 54 | } 55 | } 56 | return self; 57 | } 58 | 59 | - (void)commonInit 60 | { 61 | _floatingLabel = [UILabel new]; 62 | _floatingLabel.alpha = 0.0f; 63 | [self addSubview:_floatingLabel]; 64 | 65 | // some basic default fonts/colors 66 | _floatingLabel.font = [UIFont boldSystemFontOfSize:12.0f]; 67 | _floatingLabelTextColor = [UIColor grayColor]; 68 | _animateEvenIfNotFirstResponder = NO; 69 | _floatingLabelShowAnimationDuration = kFloatingLabelShowAnimationDuration; 70 | _floatingLabelHideAnimationDuration = kFloatingLabelHideAnimationDuration; 71 | } 72 | 73 | #pragma mark - 74 | 75 | - (UIColor *)getLabelActiveColor 76 | { 77 | if (_floatingLabelActiveTextColor) { 78 | return _floatingLabelActiveTextColor; 79 | } 80 | else if ([self respondsToSelector:@selector(tintColor)]) { 81 | return [self performSelector:@selector(tintColor)]; 82 | } 83 | return [UIColor blueColor]; 84 | } 85 | 86 | - (void)setFloatingLabelFont:(UIFont *)floatingLabelFont 87 | { 88 | _floatingLabelFont = floatingLabelFont; 89 | _floatingLabel.font = (_floatingLabelFont ? _floatingLabelFont : [UIFont boldSystemFontOfSize:12.0f]); 90 | self.placeholder = self.placeholder; // Force the label to lay itself out with the new font. 91 | } 92 | 93 | - (void)showFloatingLabel:(BOOL)animated 94 | { 95 | void (^showBlock)() = ^{ 96 | _floatingLabel.alpha = 1.0f; 97 | _floatingLabel.frame = CGRectMake(_floatingLabel.frame.origin.x, 98 | 2.0f, 99 | _floatingLabel.frame.size.width, 100 | _floatingLabel.frame.size.height); 101 | }; 102 | 103 | if (animated || _animateEvenIfNotFirstResponder) { 104 | [UIView animateWithDuration:_floatingLabelShowAnimationDuration 105 | delay:0.0f 106 | options:UIViewAnimationOptionBeginFromCurrentState|UIViewAnimationOptionCurveEaseOut 107 | animations:showBlock 108 | completion:nil]; 109 | } 110 | else { 111 | showBlock(); 112 | } 113 | } 114 | 115 | - (void)hideFloatingLabel:(BOOL)animated 116 | { 117 | void (^hideBlock)() = ^{ 118 | _floatingLabel.alpha = 0.0f; 119 | _floatingLabel.frame = CGRectMake(_floatingLabel.frame.origin.x, 120 | _floatingLabel.font.lineHeight + _floatingLabelYPadding.floatValue, 121 | _floatingLabel.frame.size.width, 122 | _floatingLabel.frame.size.height); 123 | 124 | }; 125 | 126 | if (animated || _animateEvenIfNotFirstResponder) { 127 | [UIView animateWithDuration:_floatingLabelHideAnimationDuration 128 | delay:0.0f 129 | options:UIViewAnimationOptionBeginFromCurrentState|UIViewAnimationOptionCurveEaseIn 130 | animations:hideBlock 131 | completion:nil]; 132 | } 133 | else { 134 | hideBlock(); 135 | } 136 | } 137 | 138 | - (void)setLabelOriginForTextAlignment 139 | { 140 | CGRect textRect = [self textRectForBounds:self.bounds]; 141 | 142 | CGFloat originX = textRect.origin.x; 143 | 144 | if (self.textAlignment == NSTextAlignmentCenter) { 145 | originX = textRect.origin.x + (textRect.size.width/2) - (_floatingLabel.frame.size.width/2); 146 | } 147 | else if (self.textAlignment == NSTextAlignmentRight) { 148 | originX = textRect.origin.x + textRect.size.width - _floatingLabel.frame.size.width; 149 | } else if (self.textAlignment == NSTextAlignmentNatural) { 150 | JVTextDirection baseDirection = [_floatingLabel.text getBaseDirection]; 151 | if (baseDirection == JVTextDirectionRightToLeft) { 152 | originX = textRect.origin.x + textRect.size.width - _floatingLabel.frame.size.width; 153 | } 154 | } 155 | 156 | _floatingLabel.frame = CGRectMake(originX, _floatingLabel.frame.origin.y, 157 | _floatingLabel.frame.size.width, _floatingLabel.frame.size.height); 158 | } 159 | 160 | #pragma mark - UITextField 161 | 162 | - (void)setPlaceholder:(NSString *)placeholder 163 | { 164 | [super setPlaceholder:placeholder]; 165 | 166 | _floatingLabel.text = placeholder; 167 | [_floatingLabel sizeToFit]; 168 | } 169 | 170 | - (void)setAttributedPlaceholder:(NSAttributedString *)attributedPlaceholder 171 | { 172 | [super setAttributedPlaceholder:attributedPlaceholder]; 173 | 174 | _floatingLabel.text = attributedPlaceholder.string; 175 | [_floatingLabel sizeToFit]; 176 | } 177 | 178 | - (void)setPlaceholder:(NSString *)placeholder floatingTitle:(NSString *)floatingTitle 179 | { 180 | [super setPlaceholder:placeholder]; 181 | 182 | _floatingLabel.text = floatingTitle; 183 | [_floatingLabel sizeToFit]; 184 | } 185 | 186 | - (CGRect)textRectForBounds:(CGRect)bounds 187 | { 188 | return UIEdgeInsetsInsetRect([super textRectForBounds:bounds], UIEdgeInsetsMake(ceilf(_floatingLabel.font.lineHeight+_floatingLabelYPadding.floatValue), 0.0f, 0.0f, 0.0f)); 189 | } 190 | 191 | - (CGRect)editingRectForBounds:(CGRect)bounds 192 | { 193 | return UIEdgeInsetsInsetRect([super editingRectForBounds:bounds], UIEdgeInsetsMake(ceilf(_floatingLabel.font.lineHeight+_floatingLabelYPadding.floatValue), 0.0f, 0.0f, 0.0f)); 194 | } 195 | 196 | - (CGRect)clearButtonRectForBounds:(CGRect)bounds 197 | { 198 | CGRect rect = [super clearButtonRectForBounds:bounds]; 199 | rect = CGRectMake(rect.origin.x, rect.origin.y + (_floatingLabel.font.lineHeight / 2.0) + (_floatingLabelYPadding.floatValue / 2.0f), rect.size.width, rect.size.height); 200 | return rect; 201 | } 202 | 203 | - (void)setTextAlignment:(NSTextAlignment)textAlignment 204 | { 205 | [super setTextAlignment:textAlignment]; 206 | 207 | [self setNeedsLayout]; 208 | } 209 | 210 | - (void)layoutSubviews 211 | { 212 | [super layoutSubviews]; 213 | 214 | [self setLabelOriginForTextAlignment]; 215 | 216 | if (self.floatingLabelFont) { 217 | _floatingLabel.font = self.floatingLabelFont; 218 | } 219 | 220 | BOOL firstResponder = self.isFirstResponder; 221 | _floatingLabel.textColor = (firstResponder && self.text && self.text.length > 0 ? self.getLabelActiveColor : self.floatingLabelTextColor); 222 | if (!self.text || 0 == [self.text length]) { 223 | [self hideFloatingLabel:firstResponder]; 224 | } 225 | else { 226 | [self showFloatingLabel:firstResponder]; 227 | } 228 | } 229 | 230 | #pragma mark - Accessibility 231 | 232 | - (NSString *)accessibilityLabel 233 | { 234 | NSString *accessibilityLabel; 235 | if ([self.text isEqualToString:@""] == NO) { 236 | accessibilityLabel = [self.floatingLabel accessibilityLabel]; 237 | } else { 238 | accessibilityLabel = self.text; 239 | } 240 | return accessibilityLabel; 241 | } 242 | 243 | @end 244 | -------------------------------------------------------------------------------- /AprilBeaconDemo/JVFloatLabeledTextField/JVFloatLabeledTextView.h: -------------------------------------------------------------------------------- 1 | // 2 | // JVFloatLabeledTextView.h 3 | // JVFloatLabeledTextField 4 | // 5 | // Created by Jared Verdi on 11/19/13. 6 | // Copyright (c) 2013 Jared Verdi. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface JVFloatLabeledTextView : UITextView 12 | 13 | @property (nonatomic, copy) NSString * placeholder; 14 | 15 | @property (nonatomic, strong, readonly) UILabel * floatingLabel; 16 | @property (nonatomic, strong) NSNumber * floatingLabelYPadding UI_APPEARANCE_SELECTOR; 17 | @property (nonatomic, strong) UIFont * floatingLabelFont UI_APPEARANCE_SELECTOR; 18 | @property (nonatomic, strong) UIColor * floatingLabelTextColor UI_APPEARANCE_SELECTOR; 19 | @property (nonatomic, strong) UIColor * floatingLabelActiveTextColor UI_APPEARANCE_SELECTOR; // tint color is used by default if not provided 20 | @property (nonatomic, assign) NSInteger animateEvenIfNotFirstResponder UI_APPEARANCE_SELECTOR; // Can't use BOOL for UI_APPEARANCE. Non-zero == YES 21 | @property (nonatomic, assign) NSTimeInterval floatingLabelShowAnimationDuration; 22 | @property (nonatomic, assign) NSTimeInterval floatingLabelHideAnimationDuration; 23 | 24 | /** 25 | * Sets the placeholder and the floating title 26 | * 27 | * @param placeholder The string that is displayed when there is no other text in the text view. 28 | * @param floatingTitle The string that is displayed above the text view when it's not empty. 29 | */ 30 | - (void)setPlaceholder:(NSString *)placeholder floatingTitle:(NSString *)floatingTitle; 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /AprilBeaconDemo/JVFloatLabeledTextField/JVFloatLabeledTextView.m: -------------------------------------------------------------------------------- 1 | // 2 | // JVFloatLabeledTextView.m 3 | // JVFloatLabeledTextField 4 | // 5 | // Created by Jared Verdi on 11/19/13. 6 | // Copyright (c) 2013 Jared Verdi. All rights reserved. 7 | // 8 | 9 | #import "JVFloatLabeledTextView.h" 10 | #import "NSString+TextDirectionality.h" 11 | 12 | #define kFloatingLabelShowAnimationDuration 0.3f 13 | #define kFloatingLabelHideAnimationDuration 0.3f 14 | 15 | @interface JVFloatLabeledTextView () 16 | 17 | @property (nonatomic, strong, readonly) UILabel * placeholderLabel; 18 | @property (nonatomic) CGFloat startingTextContainerInsetTop; 19 | 20 | @end 21 | 22 | @implementation JVFloatLabeledTextView 23 | 24 | - (id)initWithFrame:(CGRect)frame 25 | { 26 | self = [super initWithFrame:frame]; 27 | if (self) { 28 | [self commonInit]; 29 | } 30 | return self; 31 | } 32 | 33 | - (id)initWithCoder:(NSCoder *)aDecoder 34 | { 35 | self = [super initWithCoder:aDecoder]; 36 | if (self) { 37 | [self commonInit]; 38 | 39 | // force setter to be called on a placeholder defined in a NIB/Storyboard 40 | if (self.placeholder) { 41 | self.placeholder = self.placeholder; 42 | } 43 | } 44 | return self; 45 | } 46 | 47 | - (void)commonInit 48 | { 49 | self.startingTextContainerInsetTop = self.textContainerInset.top; 50 | 51 | _placeholderLabel = [UILabel new]; 52 | _placeholderLabel.font = self.font; 53 | _placeholderLabel.text = self.placeholder; 54 | _placeholderLabel.numberOfLines = 0; 55 | _placeholderLabel.lineBreakMode = NSLineBreakByWordWrapping; 56 | _placeholderLabel.backgroundColor = [UIColor clearColor]; 57 | _placeholderLabel.textColor = [JVFloatLabeledTextView defaultiOSPlaceholderColor]; 58 | [self insertSubview:_placeholderLabel atIndex:0]; 59 | 60 | _floatingLabel = [UILabel new]; 61 | _floatingLabel.alpha = 0.0f; 62 | [self addSubview:_floatingLabel]; 63 | 64 | // some basic default fonts/colors 65 | _floatingLabel.font = [UIFont boldSystemFontOfSize:12.0f]; 66 | _floatingLabelTextColor = [UIColor grayColor]; 67 | _animateEvenIfNotFirstResponder = NO; 68 | _floatingLabelShowAnimationDuration = kFloatingLabelShowAnimationDuration; 69 | _floatingLabelHideAnimationDuration = kFloatingLabelHideAnimationDuration; 70 | 71 | [[NSNotificationCenter defaultCenter] addObserver:self 72 | selector:@selector(layoutSubviews) 73 | name:UITextViewTextDidChangeNotification 74 | object:self]; 75 | [[NSNotificationCenter defaultCenter] addObserver:self 76 | selector:@selector(layoutSubviews) 77 | name:UITextViewTextDidBeginEditingNotification 78 | object:self]; 79 | [[NSNotificationCenter defaultCenter] addObserver:self 80 | selector:@selector(layoutSubviews) 81 | name:UITextViewTextDidEndEditingNotification 82 | object:self]; 83 | } 84 | 85 | - (void)dealloc 86 | { 87 | [[NSNotificationCenter defaultCenter] removeObserver:self 88 | name:UITextViewTextDidChangeNotification 89 | object:self]; 90 | [[NSNotificationCenter defaultCenter] removeObserver:self 91 | name:UITextViewTextDidBeginEditingNotification 92 | object:self]; 93 | [[NSNotificationCenter defaultCenter] removeObserver:self 94 | name:UITextViewTextDidEndEditingNotification 95 | object:self]; 96 | } 97 | 98 | #pragma mark - 99 | 100 | - (void)setPlaceholder:(NSString *)placeholder 101 | { 102 | _placeholder = placeholder; 103 | _placeholderLabel.text = placeholder; 104 | [_placeholderLabel sizeToFit]; 105 | 106 | _floatingLabel.text = placeholder; 107 | [_floatingLabel sizeToFit]; 108 | } 109 | 110 | - (void)setPlaceholder:(NSString *)placeholder floatingTitle:(NSString *)floatingTitle 111 | { 112 | _placeholder = placeholder; 113 | _placeholderLabel.text = placeholder; 114 | [_placeholderLabel sizeToFit]; 115 | 116 | _floatingLabel.text = floatingTitle; 117 | [_floatingLabel sizeToFit]; 118 | } 119 | 120 | - (void)layoutSubviews 121 | { 122 | [super layoutSubviews]; 123 | [self adjustTextContainerInsetTop]; 124 | 125 | CGRect textRect = [self textRect]; 126 | 127 | _placeholderLabel.alpha = [self.text length] > 0 ? 0.0f : 1.0f; 128 | _placeholderLabel.frame = CGRectMake(textRect.origin.x, textRect.origin.y, 129 | _placeholderLabel.frame.size.width, _placeholderLabel.frame.size.height); 130 | [self setLabelOriginForTextAlignment]; 131 | 132 | if (self.floatingLabelFont) { 133 | _floatingLabel.font = self.floatingLabelFont; 134 | } 135 | 136 | BOOL firstResponder = self.isFirstResponder; 137 | _floatingLabel.textColor = (firstResponder && self.text && self.text.length > 0 ? self.getLabelActiveColor : self.floatingLabelTextColor); 138 | if (!self.text || 0 == [self.text length]) { 139 | [self hideFloatingLabel:firstResponder]; 140 | } 141 | else { 142 | [self showFloatingLabel:firstResponder]; 143 | } 144 | } 145 | 146 | - (UIColor *)getLabelActiveColor 147 | { 148 | if (_floatingLabelActiveTextColor) { 149 | return _floatingLabelActiveTextColor; 150 | } 151 | else if ([self respondsToSelector:@selector(tintColor)]) { 152 | return [self performSelector:@selector(tintColor)]; 153 | } 154 | return [UIColor blueColor]; 155 | } 156 | 157 | - (void)showFloatingLabel:(BOOL)animated 158 | { 159 | void (^showBlock)() = ^{ 160 | _floatingLabel.alpha = 1.0f; 161 | _floatingLabel.frame = CGRectMake(_floatingLabel.frame.origin.x, 162 | 2.0f, 163 | _floatingLabel.frame.size.width, 164 | _floatingLabel.frame.size.height); 165 | }; 166 | 167 | if (animated || _animateEvenIfNotFirstResponder) { 168 | [UIView animateWithDuration:_floatingLabelShowAnimationDuration 169 | delay:0.0f 170 | options:UIViewAnimationOptionBeginFromCurrentState|UIViewAnimationOptionCurveEaseOut 171 | animations:showBlock 172 | completion:nil]; 173 | } 174 | else { 175 | showBlock(); 176 | } 177 | } 178 | 179 | - (void)hideFloatingLabel:(BOOL)animated 180 | { 181 | void (^hideBlock)() = ^{ 182 | _floatingLabel.alpha = 0.0f; 183 | _floatingLabel.frame = CGRectMake(_floatingLabel.frame.origin.x, 184 | _floatingLabel.font.lineHeight + _floatingLabelYPadding.floatValue, 185 | _floatingLabel.frame.size.width, 186 | _floatingLabel.frame.size.height); 187 | 188 | }; 189 | 190 | if (animated || _animateEvenIfNotFirstResponder) { 191 | [UIView animateWithDuration:_floatingLabelHideAnimationDuration 192 | delay:0.0f 193 | options:UIViewAnimationOptionBeginFromCurrentState|UIViewAnimationOptionCurveEaseIn 194 | animations:hideBlock 195 | completion:nil]; 196 | } 197 | else { 198 | hideBlock(); 199 | } 200 | } 201 | 202 | - (void)adjustTextContainerInsetTop 203 | { 204 | self.textContainerInset = UIEdgeInsetsMake(self.startingTextContainerInsetTop + _floatingLabel.font.lineHeight + _floatingLabelYPadding.floatValue, 205 | self.textContainerInset.left, self.textContainerInset.bottom, self.textContainerInset.right) ; 206 | } 207 | 208 | - (void)setLabelOriginForTextAlignment 209 | { 210 | CGFloat floatingLabelOriginX = [self textRect].origin.x; 211 | CGFloat placeholderLabelOriginX = floatingLabelOriginX; 212 | 213 | if (self.textAlignment == NSTextAlignmentCenter) { 214 | floatingLabelOriginX = (self.frame.size.width/2) - (_floatingLabel.frame.size.width/2); 215 | placeholderLabelOriginX = (self.frame.size.width/2) - (_placeholderLabel.frame.size.width/2); 216 | } 217 | else if (self.textAlignment == NSTextAlignmentRight) { 218 | floatingLabelOriginX = self.frame.size.width - _floatingLabel.frame.size.width; 219 | placeholderLabelOriginX = self.frame.size.width - _placeholderLabel.frame.size.width - self.textContainerInset.right; 220 | } else if (self.textAlignment == NSTextAlignmentNatural) { 221 | JVTextDirection baseDirection = [_floatingLabel.text getBaseDirection]; 222 | if (baseDirection == JVTextDirectionRightToLeft) { 223 | floatingLabelOriginX = self.frame.size.width - _floatingLabel.frame.size.width; 224 | placeholderLabelOriginX = self.frame.size.width - _placeholderLabel.frame.size.width - self.textContainerInset.right; 225 | } 226 | } 227 | 228 | _floatingLabel.frame = CGRectMake(floatingLabelOriginX, _floatingLabel.frame.origin.y, 229 | _floatingLabel.frame.size.width, _floatingLabel.frame.size.height); 230 | 231 | _placeholderLabel.frame = CGRectMake(placeholderLabelOriginX, _placeholderLabel.frame.origin.y, 232 | _placeholderLabel.frame.size.width, _placeholderLabel.frame.size.height); 233 | } 234 | 235 | - (CGRect)textRect 236 | { 237 | CGRect rect = UIEdgeInsetsInsetRect(self.bounds, self.contentInset); 238 | 239 | if (self.textContainer) { 240 | rect.origin.x += self.textContainer.lineFragmentPadding; 241 | rect.origin.y += self.textContainerInset.top; 242 | } 243 | 244 | return rect; 245 | } 246 | 247 | - (void)setFloatingLabelFont:(UIFont *)floatingLabelFont 248 | { 249 | _floatingLabelFont = floatingLabelFont; 250 | _floatingLabel.font = (_floatingLabelFont ? _floatingLabelFont : [UIFont boldSystemFontOfSize:12.0f]); 251 | self.placeholder = self.placeholder; // Force the label to lay itself out with the new font. 252 | } 253 | 254 | #pragma mark - Apple UITextView defaults 255 | 256 | + (UIColor *)defaultiOSPlaceholderColor 257 | { 258 | return [[UIColor lightGrayColor] colorWithAlphaComponent:0.65f]; 259 | } 260 | 261 | #pragma mark - UITextView 262 | 263 | - (void)setTextAlignment:(NSTextAlignment)textAlignment 264 | { 265 | [super setTextAlignment:textAlignment]; 266 | 267 | [self setNeedsLayout]; 268 | } 269 | 270 | - (void)setFont:(UIFont *)font 271 | { 272 | [super setFont:font]; 273 | self.placeholderLabel.font = self.font; 274 | [self layoutSubviews]; 275 | } 276 | 277 | #pragma mark - Accessibility 278 | 279 | - (NSString *)accessibilityLabel 280 | { 281 | NSString *accessibilityLabel; 282 | if ([self.text isEqualToString:@""] == NO) { 283 | accessibilityLabel = [NSString stringWithFormat:@"%@ %@",[self.floatingLabel accessibilityLabel],self.text]; 284 | } else { 285 | accessibilityLabel = [self.floatingLabel accessibilityLabel]; 286 | } 287 | return accessibilityLabel; 288 | } 289 | 290 | @end 291 | -------------------------------------------------------------------------------- /AprilBeaconDemo/JVFloatLabeledTextField/NSString+TextDirectionality.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+TextDirectionality.h 3 | // JVFloatLabeledTextField 4 | // 5 | // Created by Benjamin Briggs on 19/06/2014. 6 | // Copyright (c) 2014 Jared Verdi. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef NS_ENUM(NSUInteger, JVTextDirection) { 12 | JVTextDirectionNeutral = 0, 13 | JVTextDirectionLeftToRight, 14 | JVTextDirectionRightToLeft, 15 | }; 16 | 17 | 18 | @interface NSString (TextDirectionality) 19 | 20 | /** 21 | * Inspects the string and determins a direction 22 | * that is most likely. 23 | * 24 | * @return the direction that the string in most likely to be. 25 | */ 26 | -(JVTextDirection)getBaseDirection; 27 | 28 | @end -------------------------------------------------------------------------------- /AprilBeaconDemo/JVFloatLabeledTextField/NSString+TextDirectionality.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+TextDirectionality.m 3 | // JVFloatLabeledTextField 4 | // 5 | // Created by Benjamin Briggs on 19/06/2014. 6 | // Based on a Stack Overflow answer http://stackoverflow.com/a/13697277/900251 7 | // 8 | 9 | #import "NSString+TextDirectionality.h" 10 | 11 | @implementation NSString (TextDirectionality) 12 | 13 | // Function takes UTF32 character, and not a unichar (=UTF16 character), 14 | // because some Unicode characters need full 32 bits to represent. 15 | BOOL isCodePointStrongRTL(UTF32Char c) { 16 | return ((c == 0x5BE) || (c == 0x5C0) || (c == 0x5C3) || (c == 0x5C6) || (c >= 0x5D0 && c <= 0x5EA) || (c >= 0x5F0 && c <= 0x5F4) || (c == 0x608) || (c == 0x60B) || (c == 0x60D) || (c == 0x61B) || (c >= 0x61E && c <= 0x64A) || (c >= 0x66D && c <= 0x66F) || (c >= 0x671 && c <= 0x6D5) || (c >= 0x6E5 && c <= 0x6E6) || (c >= 0x6EE && c <= 0x6EF) || (c >= 0x6FA && c <= 0x70D) || (c >= 0x70F && c <= 0x710) || (c >= 0x712 && c <= 0x72F) || (c >= 0x74D && c <= 0x7A5) || (c == 0x7B1) || (c >= 0x7C0 && c <= 0x7EA) || (c >= 0x7F4 && c <= 0x7F5) || (c == 0x7FA) || (c >= 0x800 && c <= 0x815) || (c == 0x81A) || (c == 0x824) || (c == 0x828) || (c >= 0x830 && c <= 0x83E) || (c >= 0x840 && c <= 0x858) || (c == 0x85E) || (c == 0x8A0) || (c >= 0x8A2 && c <= 0x8AC) || (c == 0x200F) || (c == 0xFB1D) || (c >= 0xFB1F && c <= 0xFB28) || (c >= 0xFB2A && c <= 0xFB36) || (c >= 0xFB38 && c <= 0xFB3C) || (c == 0xFB3E) || (c >= 0xFB40 && c <= 0xFB41) || (c >= 0xFB43 && c <= 0xFB44) || (c >= 0xFB46 && c <= 0xFBC1) || (c >= 0xFBD3 && c <= 0xFD3D) || (c >= 0xFD50 && c <= 0xFD8F) || (c >= 0xFD92 && c <= 0xFDC7) || (c >= 0xFDF0 && c <= 0xFDFC) || (c >= 0xFE70 && c <= 0xFE74) || (c >= 0xFE76 && c <= 0xFEFC) || (c >= 0x10800 && c <= 0x10805) || (c == 0x10808) || (c >= 0x1080A && c <= 0x10835) || (c >= 0x10837 && c <= 0x10838) || (c == 0x1083C) || (c >= 0x1083F && c <= 0x10855) || (c >= 0x10857 && c <= 0x1085F) || (c >= 0x10900 && c <= 0x1091B) || (c >= 0x10920 && c <= 0x10939) || (c == 0x1093F) || (c >= 0x10980 && c <= 0x109B7) || (c >= 0x109BE && c <= 0x109BF) || (c == 0x10A00) || (c >= 0x10A10 && c <= 0x10A13) || (c >= 0x10A15 && c <= 0x10A17) || (c >= 0x10A19 && c <= 0x10A33) || (c >= 0x10A40 && c <= 0x10A47) || (c >= 0x10A50 && c <= 0x10A58) || (c >= 0x10A60 && c <= 0x10A7F) || (c >= 0x10B00 && c <= 0x10B35) || (c >= 0x10B40 && c <= 0x10B55) || (c >= 0x10B58 && c <= 0x10B72) || (c >= 0x10B78 && c <= 0x10B7F) || (c >= 0x10C00 && c <= 0x10C48) || (c >= 0x1EE00 && c <= 0x1EE03) || (c >= 0x1EE05 && c <= 0x1EE1F) || (c >= 0x1EE21 && c <= 0x1EE22) || (c == 0x1EE24) || (c == 0x1EE27) || (c >= 0x1EE29 && c <= 0x1EE32) || (c >= 0x1EE34 && c <= 0x1EE37) || (c == 0x1EE39) || (c == 0x1EE3B) || (c == 0x1EE42) || (c == 0x1EE47) || (c == 0x1EE49) || (c == 0x1EE4B) || (c >= 0x1EE4D && c <= 0x1EE4F) || (c >= 0x1EE51 && c <= 0x1EE52) || (c == 0x1EE54) || (c == 0x1EE57) || (c == 0x1EE59) || (c == 0x1EE5B) || (c == 0x1EE5D) || (c == 0x1EE5F) || (c >= 0x1EE61 && c <= 0x1EE62) || (c == 0x1EE64) || (c >= 0x1EE67 && c <= 0x1EE6A) || (c >= 0x1EE6C && c <= 0x1EE72) || (c >= 0x1EE74 && c <= 0x1EE77) || (c >= 0x1EE79 && c <= 0x1EE7C) || (c == 0x1EE7E) || (c >= 0x1EE80 && c <= 0x1EE89) || (c >= 0x1EE8B && c <= 0x1EE9B) || (c >= 0x1EEA1 && c <= 0x1EEA3) || (c >= 0x1EEA5 && c <= 0x1EEA9) || (c >= 0x1EEAB && c <= 0x1EEBB)); 17 | } 18 | 19 | BOOL isCodePointStrongLTR(UTF32Char c) { 20 | return (c >= 0x41 && c <= 0x5A) || (c >= 0x61 && c <= 0x7A) || (c == 0xAA) || (c == 0xB5) || (c == 0xBA) || (c >= 0xC0 && c <= 0xD6) || (c >= 0xD8 && c <= 0xF6) || (c >= 0xF8 && c <= 0x2B8) || (c >= 0x2BB && c <= 0x2C1) || (c >= 0x2D0 && c <= 0x2D1) || (c >= 0x2E0 && c <= 0x2E4) || (c == 0x2EE) || (c >= 0x370 && c <= 0x373) || (c >= 0x376 && c <= 0x377) || (c >= 0x37A && c <= 0x37D) || (c == 0x386) || (c >= 0x388 && c <= 0x38A) || (c == 0x38C) || (c >= 0x38E && c <= 0x3A1) || (c >= 0x3A3 && c <= 0x3F5) || (c >= 0x3F7 && c <= 0x482) || (c >= 0x48A && c <= 0x527) || (c >= 0x531 && c <= 0x556) || (c >= 0x559 && c <= 0x55F) || (c >= 0x561 && c <= 0x587) || (c == 0x589) || (c >= 0x903 && c <= 0x939) || (c == 0x93B) || (c >= 0x93D && c <= 0x940) || (c >= 0x949 && c <= 0x94C) || (c >= 0x94E && c <= 0x950) || (c >= 0x958 && c <= 0x961) || (c >= 0x964 && c <= 0x977) || (c >= 0x979 && c <= 0x97F) || (c >= 0x982 && c <= 0x983) || (c >= 0x985 && c <= 0x98C) || (c >= 0x98F && c <= 0x990) || (c >= 0x993 && c <= 0x9A8) || (c >= 0x9AA && c <= 0x9B0) || (c == 0x9B2) || (c >= 0x9B6 && c <= 0x9B9) || (c >= 0x9BD && c <= 0x9C0) || (c >= 0x9C7 && c <= 0x9C8) || (c >= 0x9CB && c <= 0x9CC) || (c == 0x9CE) || (c == 0x9D7) || (c >= 0x9DC && c <= 0x9DD) || (c >= 0x9DF && c <= 0x9E1) || (c >= 0x9E6 && c <= 0x9F1) || (c >= 0x9F4 && c <= 0x9FA) || (c == 0xA03) || (c >= 0xA05 && c <= 0xA0A) || (c >= 0xA0F && c <= 0xA10) || (c >= 0xA13 && c <= 0xA28) || (c >= 0xA2A && c <= 0xA30) || (c >= 0xA32 && c <= 0xA33) || (c >= 0xA35 && c <= 0xA36) || (c >= 0xA38 && c <= 0xA39) || (c >= 0xA3E && c <= 0xA40) || (c >= 0xA59 && c <= 0xA5C) || (c == 0xA5E) || (c >= 0xA66 && c <= 0xA6F) || (c >= 0xA72 && c <= 0xA74) || (c == 0xA83) || (c >= 0xA85 && c <= 0xA8D) || (c >= 0xA8F && c <= 0xA91) || (c >= 0xA93 && c <= 0xAA8) || (c >= 0xAAA && c <= 0xAB0) || (c >= 0xAB2 && c <= 0xAB3) || (c >= 0xAB5 && c <= 0xAB9) || (c >= 0xABD && c <= 0xAC0) || (c == 0xAC9) || (c >= 0xACB && c <= 0xACC) || (c == 0xAD0) || (c >= 0xAE0 && c <= 0xAE1) || (c >= 0xAE6 && c <= 0xAF0) || (c >= 0xB02 && c <= 0xB03) || (c >= 0xB05 && c <= 0xB0C) || (c >= 0xB0F && c <= 0xB10) || (c >= 0xB13 && c <= 0xB28) || (c >= 0xB2A && c <= 0xB30) || (c >= 0xB32 && c <= 0xB33) || (c >= 0xB35 && c <= 0xB39) || (c >= 0xB3D && c <= 0xB3E) || (c == 0xB40) || (c >= 0xB47 && c <= 0xB48) || (c >= 0xB4B && c <= 0xB4C) || (c == 0xB57) || (c >= 0xB5C && c <= 0xB5D) || (c >= 0xB5F && c <= 0xB61) || (c >= 0xB66 && c <= 0xB77) || (c == 0xB83) || (c >= 0xB85 && c <= 0xB8A) || (c >= 0xB8E && c <= 0xB90) || (c >= 0xB92 && c <= 0xB95) || (c >= 0xB99 && c <= 0xB9A) || (c == 0xB9C) || (c >= 0xB9E && c <= 0xB9F) || (c >= 0xBA3 && c <= 0xBA4) || (c >= 0xBA8 && c <= 0xBAA) || (c >= 0xBAE && c <= 0xBB9) || (c >= 0xBBE && c <= 0xBBF) || (c >= 0xBC1 && c <= 0xBC2) || (c >= 0xBC6 && c <= 0xBC8) || (c >= 0xBCA && c <= 0xBCC) || (c == 0xBD0) || (c == 0xBD7) || (c >= 0xBE6 && c <= 0xBF2) || (c >= 0xC01 && c <= 0xC03) || (c >= 0xC05 && c <= 0xC0C) || (c >= 0xC0E && c <= 0xC10) || (c >= 0xC12 && c <= 0xC28) || (c >= 0xC2A && c <= 0xC33) || (c >= 0xC35 && c <= 0xC39) || (c == 0xC3D) || (c >= 0xC41 && c <= 0xC44) || (c >= 0xC58 && c <= 0xC59) || (c >= 0xC60 && c <= 0xC61) || (c >= 0xC66 && c <= 0xC6F) || (c == 0xC7F) || (c >= 0xC82 && c <= 0xC83) || (c >= 0xC85 && c <= 0xC8C) || (c >= 0xC8E && c <= 0xC90) || (c >= 0xC92 && c <= 0xCA8) || (c >= 0xCAA && c <= 0xCB3) || (c >= 0xCB5 && c <= 0xCB9) || (c >= 0xCBD && c <= 0xCC4) || (c >= 0xCC6 && c <= 0xCC8) || (c >= 0xCCA && c <= 0xCCB) || (c >= 0xCD5 && c <= 0xCD6) || (c == 0xCDE) || (c >= 0xCE0 && c <= 0xCE1) || (c >= 0xCE6 && c <= 0xCEF) || (c >= 0xCF1 && c <= 0xCF2) || (c >= 0xD02 && c <= 0xD03) || (c >= 0xD05 && c <= 0xD0C) || (c >= 0xD0E && c <= 0xD10) || (c >= 0xD12 && c <= 0xD3A) || (c >= 0xD3D && c <= 0xD40) || (c >= 0xD46 && c <= 0xD48) || (c >= 0xD4A && c <= 0xD4C) || (c == 0xD4E) || (c == 0xD57) || (c >= 0xD60 && c <= 0xD61) || (c >= 0xD66 && c <= 0xD75) || (c >= 0xD79 && c <= 0xD7F) || (c >= 0xD82 && c <= 0xD83) || (c >= 0xD85 && c <= 0xD96) || (c >= 0xD9A && c <= 0xDB1) || (c >= 0xDB3 && c <= 0xDBB) || (c == 0xDBD) || (c >= 0xDC0 && c <= 0xDC6) || (c >= 0xDCF && c <= 0xDD1) || (c >= 0xDD8 && c <= 0xDDF) || (c >= 0xDF2 && c <= 0xDF4) || (c >= 0xE01 && c <= 0xE30) || (c >= 0xE32 && c <= 0xE33) || (c >= 0xE40 && c <= 0xE46) || (c >= 0xE4F && c <= 0xE5B) || (c >= 0xE81 && c <= 0xE82) || (c == 0xE84) || (c >= 0xE87 && c <= 0xE88) || (c == 0xE8A) || (c == 0xE8D) || (c >= 0xE94 && c <= 0xE97) || (c >= 0xE99 && c <= 0xE9F) || (c >= 0xEA1 && c <= 0xEA3) || (c == 0xEA5) || (c == 0xEA7) || (c >= 0xEAA && c <= 0xEAB) || (c >= 0xEAD && c <= 0xEB0) || (c >= 0xEB2 && c <= 0xEB3) || (c == 0xEBD) || (c >= 0xEC0 && c <= 0xEC4) || (c == 0xEC6) || (c >= 0xED0 && c <= 0xED9) || (c >= 0xEDC && c <= 0xEDF) || (c >= 0xF00 && c <= 0xF17) || (c >= 0xF1A && c <= 0xF34) || (c == 0xF36) || (c == 0xF38) || (c >= 0xF3E && c <= 0xF47) || (c >= 0xF49 && c <= 0xF6C) || (c == 0xF7F) || (c == 0xF85) || (c >= 0xF88 && c <= 0xF8C) || (c >= 0xFBE && c <= 0xFC5) || (c >= 0xFC7 && c <= 0xFCC) || (c >= 0xFCE && c <= 0xFDA) || (c >= 0x1000 && c <= 0x102C) || (c == 0x1031) || (c == 0x1038) || (c >= 0x103B && c <= 0x103C) || (c >= 0x103F && c <= 0x1057) || (c >= 0x105A && c <= 0x105D) || (c >= 0x1061 && c <= 0x1070) || (c >= 0x1075 && c <= 0x1081) || (c >= 0x1083 && c <= 0x1084) || (c >= 0x1087 && c <= 0x108C) || (c >= 0x108E && c <= 0x109C) || (c >= 0x109E && c <= 0x10C5) || (c == 0x10C7) || (c == 0x10CD) || (c >= 0x10D0 && c <= 0x1248) || (c >= 0x124A && c <= 0x124D) || (c >= 0x1250 && c <= 0x1256) || (c == 0x1258) || (c >= 0x125A && c <= 0x125D) || (c >= 0x1260 && c <= 0x1288) || (c >= 0x128A && c <= 0x128D) || (c >= 0x1290 && c <= 0x12B0) || (c >= 0x12B2 && c <= 0x12B5) || (c >= 0x12B8 && c <= 0x12BE) || (c == 0x12C0) || (c >= 0x12C2 && c <= 0x12C5) || (c >= 0x12C8 && c <= 0x12D6) || (c >= 0x12D8 && c <= 0x1310) || (c >= 0x1312 && c <= 0x1315) || (c >= 0x1318 && c <= 0x135A) || (c >= 0x1360 && c <= 0x137C) || (c >= 0x1380 && c <= 0x138F) || (c >= 0x13A0 && c <= 0x13F4) || (c >= 0x1401 && c <= 0x167F) || (c >= 0x1681 && c <= 0x169A) || (c >= 0x16A0 && c <= 0x16F0) || (c >= 0x1700 && c <= 0x170C) || (c >= 0x170E && c <= 0x1711) || (c >= 0x1720 && c <= 0x1731) || (c >= 0x1735 && c <= 0x1736) || (c >= 0x1740 && c <= 0x1751) || (c >= 0x1760 && c <= 0x176C) || (c >= 0x176E && c <= 0x1770) || (c >= 0x1780 && c <= 0x17B3) || (c == 0x17B6) || (c >= 0x17BE && c <= 0x17C5) || (c >= 0x17C7 && c <= 0x17C8) || (c >= 0x17D4 && c <= 0x17DA) || (c == 0x17DC) || (c >= 0x17E0 && c <= 0x17E9) || (c >= 0x1810 && c <= 0x1819) || (c >= 0x1820 && c <= 0x1877) || (c >= 0x1880 && c <= 0x18A8) || (c == 0x18AA) || (c >= 0x18B0 && c <= 0x18F5) || (c >= 0x1900 && c <= 0x191C) || (c >= 0x1923 && c <= 0x1926) || (c >= 0x1929 && c <= 0x192B) || (c >= 0x1930 && c <= 0x1931) || (c >= 0x1933 && c <= 0x1938) || (c >= 0x1946 && c <= 0x196D) || (c >= 0x1970 && c <= 0x1974) || (c >= 0x1980 && c <= 0x19AB) || (c >= 0x19B0 && c <= 0x19C9) || (c >= 0x19D0 && c <= 0x19DA) || (c >= 0x1A00 && c <= 0x1A16) || (c >= 0x1A19 && c <= 0x1A1B) || (c >= 0x1A1E && c <= 0x1A55) || (c == 0x1A57) || (c == 0x1A61) || (c >= 0x1A63 && c <= 0x1A64) || (c >= 0x1A6D && c <= 0x1A72) || (c >= 0x1A80 && c <= 0x1A89) || (c >= 0x1A90 && c <= 0x1A99) || (c >= 0x1AA0 && c <= 0x1AAD) || (c >= 0x1B04 && c <= 0x1B33) || (c == 0x1B35) || (c == 0x1B3B) || (c >= 0x1B3D && c <= 0x1B41) || (c >= 0x1B43 && c <= 0x1B4B) || (c >= 0x1B50 && c <= 0x1B6A) || (c >= 0x1B74 && c <= 0x1B7C) || (c >= 0x1B82 && c <= 0x1BA1) || (c >= 0x1BA6 && c <= 0x1BA7) || (c == 0x1BAA) || (c >= 0x1BAC && c <= 0x1BE5) || (c == 0x1BE7) || (c >= 0x1BEA && c <= 0x1BEC) || (c == 0x1BEE) || (c >= 0x1BF2 && c <= 0x1BF3) || (c >= 0x1BFC && c <= 0x1C2B) || (c >= 0x1C34 && c <= 0x1C35) || (c >= 0x1C3B && c <= 0x1C49) || (c >= 0x1C4D && c <= 0x1C7F) || (c >= 0x1CC0 && c <= 0x1CC7) || (c == 0x1CD3) || (c == 0x1CE1) || (c >= 0x1CE9 && c <= 0x1CEC) || (c >= 0x1CEE && c <= 0x1CF3) || (c >= 0x1CF5 && c <= 0x1CF6) || (c >= 0x1D00 && c <= 0x1DBF) || (c >= 0x1E00 && c <= 0x1F15) || (c >= 0x1F18 && c <= 0x1F1D) || (c >= 0x1F20 && c <= 0x1F45) || (c >= 0x1F48 && c <= 0x1F4D) || (c >= 0x1F50 && c <= 0x1F57) || (c == 0x1F59) || (c == 0x1F5B) || (c == 0x1F5D) || (c >= 0x1F5F && c <= 0x1F7D) || (c >= 0x1F80 && c <= 0x1FB4) || (c >= 0x1FB6 && c <= 0x1FBC) || (c == 0x1FBE) || (c >= 0x1FC2 && c <= 0x1FC4) || (c >= 0x1FC6 && c <= 0x1FCC) || (c >= 0x1FD0 && c <= 0x1FD3) || (c >= 0x1FD6 && c <= 0x1FDB) || (c >= 0x1FE0 && c <= 0x1FEC) || (c >= 0x1FF2 && c <= 0x1FF4) || (c >= 0x1FF6 && c <= 0x1FFC) || (c == 0x200E) || (c == 0x2071) || (c == 0x207F) || (c >= 0x2090 && c <= 0x209C) || (c == 0x2102) || (c == 0x2107) || (c >= 0x210A && c <= 0x2113) || (c == 0x2115) || (c >= 0x2119 && c <= 0x211D) || (c == 0x2124) || (c == 0x2126) || (c == 0x2128) || (c >= 0x212A && c <= 0x212D) || (c >= 0x212F && c <= 0x2139) || (c >= 0x213C && c <= 0x213F) || (c >= 0x2145 && c <= 0x2149) || (c >= 0x214E && c <= 0x214F) || (c >= 0x2160 && c <= 0x2188) || (c >= 0x2336 && c <= 0x237A) || (c == 0x2395) || (c >= 0x249C && c <= 0x24E9) || (c == 0x26AC) || (c >= 0x2800 && c <= 0x28FF) || (c >= 0x2C00 && c <= 0x2C2E) || (c >= 0x2C30 && c <= 0x2C5E) || (c >= 0x2C60 && c <= 0x2CE4) || (c >= 0x2CEB && c <= 0x2CEE) || (c >= 0x2CF2 && c <= 0x2CF3) || (c >= 0x2D00 && c <= 0x2D25) || (c == 0x2D27) || (c == 0x2D2D) || (c >= 0x2D30 && c <= 0x2D67) || (c >= 0x2D6F && c <= 0x2D70) || (c >= 0x2D80 && c <= 0x2D96) || (c >= 0x2DA0 && c <= 0x2DA6) || (c >= 0x2DA8 && c <= 0x2DAE) || (c >= 0x2DB0 && c <= 0x2DB6) || (c >= 0x2DB8 && c <= 0x2DBE) || (c >= 0x2DC0 && c <= 0x2DC6) || (c >= 0x2DC8 && c <= 0x2DCE) || (c >= 0x2DD0 && c <= 0x2DD6) || (c >= 0x2DD8 && c <= 0x2DDE) || (c >= 0x3005 && c <= 0x3007) || (c >= 0x3021 && c <= 0x3029) || (c >= 0x302E && c <= 0x302F) || (c >= 0x3031 && c <= 0x3035) || (c >= 0x3038 && c <= 0x303C) || (c >= 0x3041 && c <= 0x3096) || (c >= 0x309D && c <= 0x309F) || (c >= 0x30A1 && c <= 0x30FA) || (c >= 0x30FC && c <= 0x30FF) || (c >= 0x3105 && c <= 0x312D) || (c >= 0x3131 && c <= 0x318E) || (c >= 0x3190 && c <= 0x31BA) || (c >= 0x31F0 && c <= 0x321C) || (c >= 0x3220 && c <= 0x324F) || (c >= 0x3260 && c <= 0x327B) || (c >= 0x327F && c <= 0x32B0) || (c >= 0x32C0 && c <= 0x32CB) || (c >= 0x32D0 && c <= 0x32FE) || (c >= 0x3300 && c <= 0x3376) || (c >= 0x337B && c <= 0x33DD) || (c >= 0x33E0 && c <= 0x33FE) || (c == 0x3400) || (c == 0x4DB5) || (c == 0x4E00) || (c == 0x9FCC) || (c >= 0xA000 && c <= 0xA48C) || (c >= 0xA4D0 && c <= 0xA60C) || (c >= 0xA610 && c <= 0xA62B) || (c >= 0xA640 && c <= 0xA66E) || (c >= 0xA680 && c <= 0xA697) || (c >= 0xA6A0 && c <= 0xA6EF) || (c >= 0xA6F2 && c <= 0xA6F7) || (c >= 0xA722 && c <= 0xA787) || (c >= 0xA789 && c <= 0xA78E) || (c >= 0xA790 && c <= 0xA793) || (c >= 0xA7A0 && c <= 0xA7AA) || (c >= 0xA7F8 && c <= 0xA801) || (c >= 0xA803 && c <= 0xA805) || (c >= 0xA807 && c <= 0xA80A) || (c >= 0xA80C && c <= 0xA824) || (c == 0xA827) || (c >= 0xA830 && c <= 0xA837) || (c >= 0xA840 && c <= 0xA873) || (c >= 0xA880 && c <= 0xA8C3) || (c >= 0xA8CE && c <= 0xA8D9) || (c >= 0xA8F2 && c <= 0xA8FB) || (c >= 0xA900 && c <= 0xA925) || (c >= 0xA92E && c <= 0xA946) || (c >= 0xA952 && c <= 0xA953) || (c >= 0xA95F && c <= 0xA97C) || (c >= 0xA983 && c <= 0xA9B2) || (c >= 0xA9B4 && c <= 0xA9B5) || (c >= 0xA9BA && c <= 0xA9BB) || (c >= 0xA9BD && c <= 0xA9CD) || (c >= 0xA9CF && c <= 0xA9D9) || (c >= 0xA9DE && c <= 0xA9DF) || (c >= 0xAA00 && c <= 0xAA28) || (c >= 0xAA2F && c <= 0xAA30) || (c >= 0xAA33 && c <= 0xAA34) || (c >= 0xAA40 && c <= 0xAA42) || (c >= 0xAA44 && c <= 0xAA4B) || (c == 0xAA4D) || (c >= 0xAA50 && c <= 0xAA59) || (c >= 0xAA5C && c <= 0xAA7B) || (c >= 0xAA80 && c <= 0xAAAF) || (c == 0xAAB1) || (c >= 0xAAB5 && c <= 0xAAB6) || (c >= 0xAAB9 && c <= 0xAABD) || (c == 0xAAC0) || (c == 0xAAC2) || (c >= 0xAADB && c <= 0xAAEB) || (c >= 0xAAEE && c <= 0xAAF5) || (c >= 0xAB01 && c <= 0xAB06) || (c >= 0xAB09 && c <= 0xAB0E) || (c >= 0xAB11 && c <= 0xAB16) || (c >= 0xAB20 && c <= 0xAB26) || (c >= 0xAB28 && c <= 0xAB2E) || (c >= 0xABC0 && c <= 0xABE4) || (c >= 0xABE6 && c <= 0xABE7) || (c >= 0xABE9 && c <= 0xABEC) || (c >= 0xABF0 && c <= 0xABF9) || (c == 0xAC00) || (c == 0xD7A3) || (c >= 0xD7B0 && c <= 0xD7C6) || (c >= 0xD7CB && c <= 0xD7FB) || (c == 0xD800) || (c >= 0xDB7F && c <= 0xDB80) || (c >= 0xDBFF && c <= 0xDC00) || (c >= 0xDFFF && c <= 0xE000) || (c >= 0xF8FF && c <= 0xFA6D) || (c >= 0xFA70 && c <= 0xFAD9) || (c >= 0xFB00 && c <= 0xFB06) || (c >= 0xFB13 && c <= 0xFB17) || (c >= 0xFF21 && c <= 0xFF3A) || (c >= 0xFF41 && c <= 0xFF5A) || (c >= 0xFF66 && c <= 0xFFBE) || (c >= 0xFFC2 && c <= 0xFFC7) || (c >= 0xFFCA && c <= 0xFFCF) || (c >= 0xFFD2 && c <= 0xFFD7) || (c >= 0xFFDA && c <= 0xFFDC) || (c >= 0x10000 && c <= 0x1000B) || (c >= 0x1000D && c <= 0x10026) || (c >= 0x10028 && c <= 0x1003A) || (c >= 0x1003C && c <= 0x1003D) || (c >= 0x1003F && c <= 0x1004D) || (c >= 0x10050 && c <= 0x1005D) || (c >= 0x10080 && c <= 0x100FA) || (c == 0x10100) || (c == 0x10102) || (c >= 0x10107 && c <= 0x10133) || (c >= 0x10137 && c <= 0x1013F) || (c >= 0x101D0 && c <= 0x101FC) || (c >= 0x10280 && c <= 0x1029C) || (c >= 0x102A0 && c <= 0x102D0) || (c >= 0x10300 && c <= 0x1031E) || (c >= 0x10320 && c <= 0x10323) || (c >= 0x10330 && c <= 0x1034A) || (c >= 0x10380 && c <= 0x1039D) || (c >= 0x1039F && c <= 0x103C3) || (c >= 0x103C8 && c <= 0x103D5) || (c >= 0x10400 && c <= 0x1049D) || (c >= 0x104A0 && c <= 0x104A9) || (c == 0x11000) || (c >= 0x11002 && c <= 0x11037) || (c >= 0x11047 && c <= 0x1104D) || (c >= 0x11066 && c <= 0x1106F) || (c >= 0x11082 && c <= 0x110B2) || (c >= 0x110B7 && c <= 0x110B8) || (c >= 0x110BB && c <= 0x110C1) || (c >= 0x110D0 && c <= 0x110E8) || (c >= 0x110F0 && c <= 0x110F9) || (c >= 0x11103 && c <= 0x11126) || (c == 0x1112C) || (c >= 0x11136 && c <= 0x11143) || (c >= 0x11182 && c <= 0x111B5) || (c >= 0x111BF && c <= 0x111C8) || (c >= 0x111D0 && c <= 0x111D9) || (c >= 0x11680 && c <= 0x116AA) || (c == 0x116AC) || (c >= 0x116AE && c <= 0x116AF) || (c == 0x116B6) || (c >= 0x116C0 && c <= 0x116C9) || (c >= 0x12000 && c <= 0x1236E) || (c >= 0x12400 && c <= 0x12462) || (c >= 0x12470 && c <= 0x12473) || (c >= 0x13000 && c <= 0x1342E) || (c >= 0x16800 && c <= 0x16A38) || (c >= 0x16F00 && c <= 0x16F44) || (c >= 0x16F50 && c <= 0x16F7E) || (c >= 0x16F93 && c <= 0x16F9F) || (c >= 0x1B000 && c <= 0x1B001) || (c >= 0x1D000 && c <= 0x1D0F5) || (c >= 0x1D100 && c <= 0x1D126) || (c >= 0x1D129 && c <= 0x1D166) || (c >= 0x1D16A && c <= 0x1D172) || (c >= 0x1D183 && c <= 0x1D184) || (c >= 0x1D18C && c <= 0x1D1A9) || (c >= 0x1D1AE && c <= 0x1D1DD) || (c >= 0x1D360 && c <= 0x1D371) || (c >= 0x1D400 && c <= 0x1D454) || (c >= 0x1D456 && c <= 0x1D49C) || (c >= 0x1D49E && c <= 0x1D49F) || (c == 0x1D4A2) || (c >= 0x1D4A5 && c <= 0x1D4A6) || (c >= 0x1D4A9 && c <= 0x1D4AC) || (c >= 0x1D4AE && c <= 0x1D4B9) || (c == 0x1D4BB) || (c >= 0x1D4BD && c <= 0x1D4C3) || (c >= 0x1D4C5 && c <= 0x1D505) || (c >= 0x1D507 && c <= 0x1D50A) || (c >= 0x1D50D && c <= 0x1D514) || (c >= 0x1D516 && c <= 0x1D51C) || (c >= 0x1D51E && c <= 0x1D539) || (c >= 0x1D53B && c <= 0x1D53E) || (c >= 0x1D540 && c <= 0x1D544) || (c == 0x1D546) || (c >= 0x1D54A && c <= 0x1D550) || (c >= 0x1D552 && c <= 0x1D6A5) || (c >= 0x1D6A8 && c <= 0x1D6DA) || (c >= 0x1D6DC && c <= 0x1D714) || (c >= 0x1D716 && c <= 0x1D74E) || (c >= 0x1D750 && c <= 0x1D788) || (c >= 0x1D78A && c <= 0x1D7C2) || (c >= 0x1D7C4 && c <= 0x1D7CB) || (c >= 0x1F110 && c <= 0x1F12E) || (c >= 0x1F130 && c <= 0x1F169) || (c >= 0x1F170 && c <= 0x1F19A) || (c >= 0x1F1E6 && c <= 0x1F202) || (c >= 0x1F210 && c <= 0x1F23A) || (c >= 0x1F240 && c <= 0x1F248) || (c >= 0x1F250 && c <= 0x1F251) || (c == 0x20000) || (c == 0x2A6D6) || (c == 0x2A700) || (c == 0x2B734) || (c == 0x2B740) || (c == 0x2B81D) || (c >= 0x2F800 && c <= 0x2FA1D) || (c == 0xF0000) || (c == 0xFFFFD) || (c == 0x100000) || (c == 0x10FFFD); 21 | } 22 | 23 | -(JVTextDirection)getBaseDirection { 24 | // Decode string into UTF32. 25 | NSData *utf32data = [self dataUsingEncoding:NSUTF32StringEncoding]; 26 | // NSUTF32StringEncoding has the platform's byte-order, which should 27 | // be the same as UTF32Char's. 28 | UTF32Char *utf32chars = (UTF32Char *)[utf32data bytes]; 29 | 30 | for (NSUInteger i = 0; i < self.length; i++) { 31 | // UTF32 is a fixed-length encoding, so utf32chars[i] will 32 | // always give us the i'th character. 33 | if (isCodePointStrongRTL(utf32chars[i])) 34 | return JVTextDirectionRightToLeft; 35 | if (isCodePointStrongLTR(utf32chars[i])) 36 | return JVTextDirectionLeftToRight; 37 | } 38 | return JVTextDirectionNeutral; 39 | } 40 | 41 | @end -------------------------------------------------------------------------------- /AprilBeaconDemo/tile_floor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AprilBrother/AprilBeacon-iOS-SDK/6b558be7052c58e739e8eeb7e33411c95598f435/AprilBeaconDemo/tile_floor.png -------------------------------------------------------------------------------- /AprilSDK.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = "AprilSDK" 3 | s.version = "2.0.6" 4 | s.summary = "AprilBeacon SDK for iOS, use this library communicate with beacons." 5 | s.homepage = "https://github.com/AprilBrother/AprilBeacon-iOS-SDK" 6 | s.author = { "AprilBrother" => "tech@aprbrother.com" } 7 | s.platform = :ios 8 | s.ios.deployment_target = '7.0' 9 | s.source = { :git => "https://github.com/AprilBrother/AprilBeacon-iOS-SDK.git", :tag => s.version.to_s } 10 | s.source_files = 'AprilSDK/Headers/*.{h}' 11 | s.preserve_paths = 'AprilSDK/libAprilBeaconSDK.a' 12 | s.vendored_libraries = 'AprilSDK/libAprilBeaconSDK.a' 13 | s.requires_arc = true 14 | s.xcconfig = { 'LIBRARY_SEARCH_PATHS' => '$(PODS_ROOT)/AprilSDK', 15 | 'OTHER_LDFLAGS' => '-all_load' } 16 | s.license = { 17 | :type => 'Copyright', 18 | :text => <<-LICENSE 19 | Copyright 2016 AprilBrother LLC, Inc. All rights reserved. 20 | LICENSE 21 | } 22 | end 23 | -------------------------------------------------------------------------------- /AprilSDK/Headers/ABBeacon.h: -------------------------------------------------------------------------------- 1 | // 2 | // ABBeacon.h 3 | // AprilBeaconSDK 4 | // 5 | // Created by AprilBrother LLC on 14-4-1. 6 | // Copyright (c) 2014年 AprilBrother LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "ABDefinitions.h" 11 | 12 | @import CoreBluetooth; 13 | @import CoreLocation; 14 | 15 | @class ABBeacon; 16 | 17 | //////////////////////////////////////////////////////////////////// 18 | // April beacon delegate protocol 19 | 20 | /** 21 | 22 | ABBeaconDelegate defines beacon connection delegate mathods. Connection is asynchronous operation so you need to be prepared that eg. beaconDidDisconnectWith: method can be invoked without previous action. 23 | 24 | */ 25 | 26 | @protocol ABBeaconDelegate 27 | 28 | @optional 29 | 30 | 31 | /** 32 | * Delegate method that beacon did connected with error. 33 | * if error is not nil, means beacon didn't be connected 34 | * or beacon connected 35 | * 36 | * @param beacon reference to beacon object 37 | * @param error beacon connect failed error or nil 38 | * 39 | * @return void 40 | */ 41 | - (void)beaconDidConnected:(ABBeacon*)beacon withError:(NSError *)error; 42 | 43 | /** 44 | * Delegate method that beacon did disconnect with device. 45 | * 46 | * @param beacon reference to beacon object 47 | * @param error information about reason of error 48 | * 49 | * @return void 50 | */ 51 | - (void)beaconDidDisconnect:(ABBeacon*)beacon withError:(NSError*)error; 52 | 53 | @end 54 | 55 | /** 56 | 57 | ABBeacon defines properties of April beacon, you can get parameters of iBeacon from ABBeacon 58 | 59 | */ 60 | 61 | @interface ABBeacon : NSObject 62 | 63 | @property (nonatomic, weak) id delegate; 64 | 65 | /// @name Publicly available properties 66 | 67 | /** 68 | * proximityUUID 69 | * 70 | * Proximity identifier associated with the beacon. 71 | * 72 | */ 73 | @property (nonatomic, strong) NSUUID* proximityUUID; 74 | 75 | 76 | /** 77 | * major 78 | * 79 | * Most significant value associated with the region. If a major value wasn't specified, this will be nil. 80 | * 81 | */ 82 | @property (nonatomic, strong) NSNumber* major; 83 | 84 | /** 85 | * minor 86 | * 87 | * Least significant value associated with the region. If a minor value wasn't specified, this will be nil. 88 | * 89 | */ 90 | @property (nonatomic, strong) NSNumber* minor; 91 | 92 | /** 93 | * rssi 94 | * 95 | * Received signal strength in decibels of the specified beacon. 96 | * This value is an average of the RSSI samples collected since this beacon was last reported. 97 | * 98 | */ 99 | @property (nonatomic) NSInteger rssi; 100 | 101 | /** 102 | * proximity 103 | * 104 | * The value in this property gives a general sense of the relative distance to the beacon. Use it to quickly identify beacons that are nearer to the user rather than farther away. 105 | */ 106 | @property (nonatomic) CLProximity proximity; 107 | 108 | /** 109 | * macAddress 110 | * 111 | * Discussion: 112 | * Hardware MAC address of the beacon. 113 | */ 114 | @property (nonatomic, strong) NSString * macAddress; 115 | 116 | /** 117 | * proximity 118 | * 119 | * The value in this property gives a general sense of the relative distance to the beacon. Use it to quickly identify beacons that are nearer to the user rather than farther away. 120 | */ 121 | @property (nonatomic, strong) NSNumber* distance; 122 | 123 | /** 124 | * measuredPower 125 | * 126 | * rssi value measured from 1m. This value is used for device calibration. 127 | */ 128 | @property (nonatomic, strong) NSNumber* measuredPower; 129 | 130 | ///////////////////////////////////////////////////// 131 | // properties filled when read characteristic 132 | 133 | /// @name Properties available after connection 134 | 135 | /** 136 | * peripheral 137 | * 138 | * peripheral object of beacon. 139 | */ 140 | @property (nonatomic, strong) CBPeripheral* peripheral; 141 | 142 | /** 143 | * firmwareUpdateInfo 144 | * 145 | * Flag indicating connection status. 146 | */ 147 | @property (nonatomic, readonly) BOOL isConnected; 148 | 149 | /** 150 | * beacon power 151 | * 152 | * enum values of power, @see ABTxPower. 153 | */ 154 | @property (nonatomic) ABTxPower txPower; 155 | 156 | /** 157 | * advInterval 158 | * 159 | * Advertising interval of the beacon. Value change from 100ms to 2000ms, The unit is 100ms. Value available after connection with the beacon 160 | */ 161 | @property (nonatomic, strong) NSNumber* advInterval; 162 | 163 | /** 164 | * batteryLevel 165 | * 166 | * Battery strength in %. Battery level change from 100% - 0%. Value available after connection with the beacon 167 | */ 168 | @property (nonatomic, strong) NSNumber* batteryLevel; 169 | 170 | /** 171 | * firmwareRevision 172 | * 173 | * Firmware revision of beacon. Value available after connection with the beacon 174 | */ 175 | @property (nonatomic, strong) NSString* firmwareRevision; 176 | 177 | /** 178 | * manufacturerName 179 | * 180 | * Manufacturer name of beacon. Value available after connection with the beacon 181 | */ 182 | @property (nonatomic, strong) NSString* manufacturerName; 183 | 184 | /** 185 | * modelNumber 186 | * 187 | * Model number of beacon. Value available after connection with the beacon 188 | */ 189 | @property (nonatomic, strong) NSString* modelNumber; 190 | 191 | /** 192 | * isSupportEddystone 193 | * 194 | * is beacon support Google Eddystone protocol. Value available after connection with the beacon 195 | */ 196 | @property (nonatomic) BOOL isSupportEddystone; 197 | 198 | /** 199 | * broadcastType 200 | * 201 | * if isSupportEddystone is true, use this to check the broadcast type. Value available after connection with the beacon 202 | * ABBeaconBroadcastiBeacon Default type 203 | * ABBeaconBroadcastEddystoneUid broadcast UUID is proximityUUID 204 | * ABBeaconBroadcastEddystoneURL broadcast URL is eddyStoneURL 205 | */ 206 | @property (nonatomic) ABBroadcastType broadcastType; 207 | 208 | /** 209 | * eddyStoneURL 210 | * 211 | * if broadcast type is ABBeaconBroadcastEddystoneURL, use this to get broadcast URL. Value available after connection with the beacon 212 | */ 213 | @property (nonatomic, strong) NSString* eddyStoneURL; 214 | 215 | 216 | /// @name Connection handling methods 217 | 218 | 219 | /** 220 | * Connect to particular beacon using bluetooth. 221 | * Connection is required to change values like 222 | * Major, Minor, Power and Advertising interval. 223 | * 224 | * @return void 225 | */ 226 | - (void)connectToBeacon; 227 | 228 | /** 229 | * Disconnect device with particular beacon 230 | * 231 | * @return void 232 | */ 233 | - (void)disconnectBeacon; 234 | 235 | /** 236 | * Writes beacon info to connected beacon 237 | * If you set the password to nil, it will use the default password 238 | * If you set value to nil, it won't modify the value 239 | * 240 | * 241 | * @param password auth password, default 'AprilBrother' 242 | * @param uuidString new Proximity UUID value 243 | * @param major new major of iBeacon 244 | * @param minor new minro of iBeacon 245 | * @param txPower @(ABTxPower) tx power 246 | * @param advInterval advertise interval 247 | * @param measuredPower measured power of iBeacon 248 | * @param newpassword new password 249 | * @param completion callback 250 | * 251 | * @return void 252 | */ 253 | - (void)writeBeaconInfoByPassword:(NSString *)password 254 | uuid:(NSString *)uuidString 255 | major:(NSNumber *)major 256 | minor:(NSNumber *)minor 257 | txPower:(NSNumber *)txPower 258 | advInterval:(NSNumber *)advInterval 259 | measuredPower:(NSNumber *)measuredPower 260 | newpassword:(NSString *)newpassword 261 | withCompletion:(ABCompletionBlock)completion; 262 | 263 | /** 264 | * Writes beacon info to connected beacon 265 | * If you set the password to nil, it will use the default password 266 | * If you set value to nil, it won't modify the value 267 | * 268 | * 269 | * @param password auth password, default 'AprilBrother', '195660' for EEK beacon 270 | * @param uuidString new Proximity UUID value 271 | * @param major new major of iBeacon 272 | * @param minor new minro of iBeacon 273 | * @param txPower @(ABTxPower) tx power 274 | * @param advInterval advertise interval 275 | * @param measuredPower measured power of iBeacon 276 | * @param newpassword new password 277 | * @param completion callback 278 | * @param type broadcast type 279 | * 280 | * @return void 281 | */ 282 | - (void)writeBeaconInfoByPassword:(NSString *)password 283 | uuid:(NSString *)uuidString 284 | major:(NSNumber *)major 285 | minor:(NSNumber *)minor 286 | txPower:(NSNumber *)txPower 287 | advInterval:(NSNumber *)advInterval 288 | measuredPower:(NSNumber *)measuredPower 289 | newpassword:(NSString *)newpassword 290 | broadcastType:(ABBroadcastType)type 291 | withCompletion:(ABCompletionBlock)completion; 292 | 293 | /** 294 | * Writes beacon info to connected beacon 295 | * If you set the password to nil, it will use the default password 296 | * If you set value to nil, it won't modify the value 297 | * 298 | * 299 | * @param url broadcast url 300 | * @param type broadcast type 301 | * @param password auth password, default 'AprilBrother', '195660' for EEK beacon 302 | * @param completion callback 303 | * 304 | * @return void 305 | */ 306 | - (void)writeEddyStoneURLAndReset:(NSString *)url 307 | broadcastType:(ABBroadcastType)type 308 | password:(NSString *)password 309 | txPower:(NSNumber *)txPower 310 | advInterval:(NSNumber *)advInterval 311 | newpassword:(NSString *)newpassword 312 | completion:(ABCompletionBlock)completion; 313 | 314 | /** 315 | * Writes beacon info to connected beacon 316 | * If you set the password to nil, it will use the default password 317 | * If you set value to nil, it won't modify the value 318 | * 319 | * 320 | * @param uuidString broadcast UUID 321 | * @param type broadcast type 322 | * @param password auth password, default 'AprilBrother', '195660' for EEK beacon 323 | * @param completion callback 324 | * 325 | * @return void 326 | */ 327 | - (void)writeEddyStoneUidAndReset:(NSString *)uuidString 328 | broadcastType:(ABBroadcastType)type 329 | password:(NSString *)password 330 | txPower:(NSNumber *)txPower 331 | advInterval:(NSNumber *)advInterval 332 | newpassword:(NSString *)newpassword 333 | completion:(ABCompletionBlock)completion; 334 | 335 | /** 336 | * Writes AT command to connected beacon 337 | * 338 | * 339 | * @param data writing data 340 | * @param completion callback 341 | * 342 | * @return void 343 | */ 344 | - (void)writeCommandWithData:(NSData *)data 345 | completion:(ABCompletionBlock)completion; 346 | 347 | @end 348 | -------------------------------------------------------------------------------- /AprilSDK/Headers/ABBeaconManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // ABBeaconManager.h 3 | // AprilBeaconSDK 4 | // 5 | // Created by AprilBrother LLC on 14-4-1. 6 | // Copyright (c) 2014年 AprilBrother LLC. All rights reserved. 7 | // version 2.0.3 8 | 9 | #import 10 | #import "ABBeaconRegion.h" 11 | 12 | @import CoreBluetooth; 13 | @import CoreLocation; 14 | 15 | @class ABBeaconManager; 16 | @class ABBeacon; 17 | /** 18 | 19 | The ABBeaconManagerDelegate protocol defines the delegate methods to respond for related events. 20 | */ 21 | 22 | @protocol ABBeaconManagerDelegate 23 | 24 | @optional 25 | 26 | /** 27 | * Delegate method invoked during ranging. 28 | * Allows to retrieve NSArray of all discoverd beacons 29 | * represented with ABBeacon objects. 30 | * 31 | * @param manager April beacon manager 32 | * @param beacons all beacons as ABBeacon objects 33 | * @param region April beacon region 34 | * 35 | * @return void 36 | */ 37 | - (void)beaconManager:(ABBeaconManager *)manager 38 | didRangeBeacons:(NSArray *)beacons 39 | inRegion:(ABBeaconRegion *)region; 40 | 41 | /** 42 | * Delegate method invoked when ranging fails 43 | * for particular region. Related NSError object passed. 44 | * 45 | * @param manager April beacon manager 46 | * @param region April beacon region 47 | * @param error object containing error info 48 | * 49 | * @return void 50 | */ 51 | - (void)beaconManager:(ABBeaconManager *)manager 52 | rangingBeaconsDidFailForRegion:(ABBeaconRegion *)region 53 | withError:(NSError *)error; 54 | 55 | 56 | /** 57 | * Delegate method invoked when monitoring fails 58 | * for particular region. Related NSError object passed. 59 | * 60 | * @param manager April beacon manager 61 | * @param region April beacon region 62 | * @param error object containing error info 63 | * 64 | * @return void 65 | */ 66 | - (void)beaconManager:(ABBeaconManager *)manager 67 | monitoringDidFailForRegion:(ABBeaconRegion *)region 68 | withError:(NSError *)error; 69 | /** 70 | * Method triggered when iOS device enters April 71 | * beacon region during monitoring. 72 | * 73 | * @param manager April beacon manager 74 | * @param region April beacon region 75 | * 76 | * @return void 77 | */ 78 | - (void)beaconManager:(ABBeaconManager *)manager 79 | didEnterRegion:(ABBeaconRegion *)region; 80 | 81 | 82 | /** 83 | * Method triggered when iOS device leaves April 84 | * beacon region during monitoring. 85 | * 86 | * @param manager April beacon manager 87 | * @param region April beacon region 88 | * 89 | * @return void 90 | */ 91 | - (void)beaconManager:(ABBeaconManager *)manager 92 | didExitRegion:(ABBeaconRegion *)region; 93 | 94 | /** 95 | * Method triggered when April beacon region state 96 | * was determined using requestStateForRegion: 97 | * 98 | * @param manager April beacon manager 99 | * @param state April beacon region state 100 | * @param region April beacon region 101 | * 102 | * @return void 103 | */ 104 | - (void)beaconManager:(ABBeaconManager *)manager 105 | didDetermineState:(CLRegionState)state 106 | forRegion:(ABBeaconRegion *)region; 107 | 108 | /** 109 | * Method triggered when device starts advertising 110 | * as iBeacon. 111 | * 112 | * @param manager April beacon manager 113 | * @param error info about any error 114 | * 115 | * @return void 116 | */ 117 | - (void)beaconManagerDidStartAdvertising:(ABBeaconManager *)manager 118 | error:(NSError *)error; 119 | 120 | @end 121 | 122 | 123 | 124 | /** 125 | 126 | The ABBeaconManager class defines the interface for handling and configuring the April beacons and get related events to your application. You use an instance of this class to establish the parameters that describes each beacon behavior. You can also use a beacon manager object to retrieve all beacons in range. 127 | 128 | A beacon manager object provides support for the following location-related activities: 129 | 130 | * Monitoring distinct regions of interest and generating location events when the user enters or leaves those regions (works in background mode). 131 | * Reporting the range to nearby beacons and ther distance for the device. 132 | 133 | */ 134 | 135 | @interface ABBeaconManager : NSObject 136 | 137 | @property (nonatomic, weak) id delegate; 138 | 139 | /** 140 | Allows to avoid beacons with unknown state (proximity == 0), when ranging. Default value is NO. 141 | */ 142 | @property (nonatomic) BOOL avoidUnknownStateBeacons; 143 | 144 | /* 145 | * authorizationStatus 146 | * 147 | * Discussion: 148 | * Get current authorization status 149 | * @return current authorization status 150 | */ 151 | + (CLAuthorizationStatus)authorizationStatus; 152 | 153 | /* 154 | * requestWhenInUseAuthorization 155 | * 156 | * Discussion: 157 | * Request location when in use authorization 158 | */ 159 | 160 | - (void)requestWhenInUseAuthorization; 161 | /* 162 | * requestAlwaysAuthorization 163 | * 164 | * Discussion: 165 | * Request location always useage authorization 166 | */ 167 | - (void)requestAlwaysAuthorization; 168 | 169 | /* 170 | * monitoredRegions 171 | * 172 | * Discussion: 173 | * Retrieve a set of objects for the regions that are currently being monitored. If any Beacon manager 174 | * has been instructed to monitor a region, during this or previous launches of your application, it will 175 | * be present in this set. 176 | */ 177 | - (NSSet *)monitoredRegions; 178 | 179 | /* 180 | * rangedRegions 181 | * 182 | * Discussion: 183 | * Retrieve a set of objects representing the regions for which this Beacon manager is actively providing ranging. 184 | */ 185 | - (NSSet *)rangedRegions; 186 | 187 | /// @name CoreLocation based iBeacon monitoring and ranging methods 188 | 189 | /** 190 | * Range all April beacons that are visible in range. 191 | * Delegate method beaconManager:didRangeBeacons:inRegion: 192 | * is used to retrieve found beacons. Returned NSArray contains 193 | * ABBeacon objects. 194 | * 195 | * @param region April beacon region 196 | * 197 | * @return void 198 | */ 199 | - (void)startRangingBeaconsInRegion:(ABBeaconRegion*)region; 200 | 201 | /** 202 | * Stops ranging April beacons. 203 | * 204 | * @param region April beacon region 205 | * 206 | * @return void 207 | */ 208 | - (void)stopRangingBeaconsInRegion:(ABBeaconRegion*)region; 209 | 210 | /** 211 | * Start monitoring for particular region. 212 | * Functionality works in the background mode as well. 213 | * Every time you enter or leave region appropriet 214 | * delegate method inovked: beaconManager:didEnterRegtion: 215 | * and beaconManager:didExitRegion: 216 | * 217 | * @param region April beacon region 218 | * 219 | * @return void 220 | */ 221 | - (void)startMonitoringForRegion:(ABBeaconRegion*)region; 222 | 223 | /** 224 | * Unsubscribe application from iOS monitoring of 225 | * April beacon region. 226 | * 227 | * @param region April beacon region 228 | * 229 | * @return void 230 | */ 231 | - (void)stopMonitoringForRegion:(ABBeaconRegion *)region; 232 | 233 | /** 234 | * Allows to validate current state for particular region 235 | * 236 | * @param region April beacon region 237 | * 238 | * @return void 239 | */ 240 | - (void)requestStateForRegion:(ABBeaconRegion *)region; 241 | 242 | /// @name Turning device into iBeacon 243 | 244 | /** 245 | * Allows to turn device into virtual April beacon. 246 | * 247 | * @param proximityUUID proximity UUID beacon value 248 | * @param major minor beacon value 249 | * @param minor major beacon value 250 | * @param identifier unique identifier for you region 251 | * 252 | * @return void 253 | */ 254 | - (void)startAdvertisingWithProximityUUID:(NSUUID *)proximityUUID 255 | major:(CLBeaconMajorValue)major 256 | minor:(CLBeaconMinorValue)minor 257 | identifier:(NSString*)identifier; 258 | 259 | /** 260 | * Stop beacon advertising 261 | * 262 | * @return void 263 | */ 264 | - (void)stopAdvertising; 265 | 266 | @end -------------------------------------------------------------------------------- /AprilSDK/Headers/ABBeaconRegion.h: -------------------------------------------------------------------------------- 1 | // 2 | // ABBeaconRegion.h 3 | // AprilBeaconSDK 4 | // 5 | // Created by AprilBrother LLC on 14-4-1. 6 | // Copyright (c) 2014 AprilBrother LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @import CoreLocation; 12 | 13 | /** 14 | 15 | A ABBeaconRegion object defines a type of region that is based on the device’s proximity to a Bluetooth beacon, as opposed to a geographic location. A beacon region looks for devices whose identifying information matches the information you provide. When that device comes in range, the region triggers the delivery of an appropriate notification. 16 | 17 | You can monitor beacon regions in two ways. To receive notifications when a device enters or exits the vicinity of a beacon, use the startMonitoringForRegion: method of your location manager object. While a beacon is in range, you can also call the startRangingBeaconsInRegion: method to begin receiving notifications when the relative distance to the beacon changes. 18 | 19 | ABBeaconRegion extends basic CLBeaconRegion Core Location object, 20 | 21 | */ 22 | 23 | @interface ABBeaconRegion : CLBeaconRegion 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /AprilSDK/Headers/ABBluetoothManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // ABBluetoothManager.h 3 | // ConfigTool 4 | // 5 | // Created by gongliang on 15/7/21. 6 | // Copyright (c) 2015年 April Brother. All rights reserved. 7 | // 8 | 9 | #import 10 | @class ABBeacon; 11 | 12 | @class ABBluetoothManager; 13 | 14 | /** 15 | 16 | The ABBluetoothManagerDelegate protocol defines the delegate methods to respond for related events. 17 | */ 18 | 19 | @protocol ABBluetoothManagerDelegate 20 | 21 | @optional 22 | 23 | /** 24 | * Delegate method invoked to handle discovered 25 | * ABBeacon objects using CoreBluetooth framework 26 | * in particular region. 27 | * 28 | * @param manager April beacon manager 29 | * @param beacons all beacons as ABBeacon objects 30 | * 31 | * @return void 32 | */ 33 | - (void)beaconManager:(ABBluetoothManager *)manager 34 | didDiscoverBeacons:(NSArray *)beacons; 35 | 36 | /** 37 | * Delegate method invoked to handle discovered 38 | * ABBeacon object using CoreBluetooth framework 39 | * in particular region. 40 | * 41 | * @param manager April beacon manager 42 | * @param beacon return single beacon once, not all beacons, 43 | * diffent from beaconManager:manager didDiscoverBeacons: 44 | * 45 | * @return void 46 | */ 47 | - (void)beaconManager:(ABBluetoothManager *)manager 48 | didDiscoverBeacon:(ABBeacon *)beacon; 49 | 50 | @end 51 | 52 | /** 53 | 54 | ABBluetoothManager defines method to discover April beacons 55 | 56 | */ 57 | 58 | @interface ABBluetoothManager : NSObject 59 | 60 | @property (nonatomic, weak) id delegate; 61 | 62 | /** 63 | * Start beacon discovery process based on CoreBluetooth 64 | * framework. Method is useful for finding all April beacons 65 | * 66 | * @return void 67 | */ 68 | - (void)startAprilBeaconsDiscovery; 69 | 70 | /** 71 | * Start sensor discovery process based on CoreBluetooth 72 | * framework. Method is useful for finding april sensors only 73 | * 74 | * @return void 75 | */ 76 | - (void)startAprilSensorsDiscovery; 77 | 78 | 79 | /** 80 | * Start light discovery process based on CoreBluetooth 81 | * framework. Method is useful for finding april light only 82 | * 83 | * @return void 84 | */ 85 | - (void)startAprilLightDiscovery; 86 | 87 | /** 88 | * Stops CoreBluetooth based beacon discovery process. 89 | * 90 | * @return void 91 | */ 92 | - (void)stopAprilBeaconDiscovery; 93 | 94 | /** 95 | * Clear beacons Data and Stops CoreBluetooth based beacon discovery process. 96 | */ 97 | - (void)stopAndClearDataAprilBeaconDiscovery; 98 | 99 | /** 100 | * Beacons whose name begin with specified name can be found. 101 | * 102 | * @param beaconPrefixName name want to discovered 103 | * @return void 104 | */ 105 | - (void)addCustomBeaconNameFilter:(NSString *)beaconPrefixName; 106 | 107 | /** 108 | * Remove filter of specified name. 109 | * 110 | * @param beaconPrefixName name want to removed from filter; 111 | * @return void 112 | */ 113 | - (void)removeCustomBeaconNameFilter:(NSString *)beaconPrefixName; 114 | 115 | 116 | @end 117 | -------------------------------------------------------------------------------- /AprilSDK/Headers/ABDefinitions.h: -------------------------------------------------------------------------------- 1 | // 2 | // ABDefinitions.h 3 | // ConfigTool 4 | // 5 | // Created by gongliang on 15/7/21. 6 | // Copyright (c) 2015年 April Brother. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | /// April Beacon power value definition 12 | typedef NS_ENUM(NSInteger, ABTxPower) { 13 | /** Default value for tx power */ 14 | ABTxPower0DBM = 0, 15 | /** The max value for tx power */ 16 | ABTxPower4DBM = 1, 17 | /** Small value for tx power */ 18 | ABTxPowerMinus6DBM = 2, 19 | /** The value for tx power */ 20 | ABTxPowerMinus23DBM = 3, 21 | /** Tx power definition, only used in EEK beacon */ 22 | ABTxPowerMinus20DBM = 4 23 | }; 24 | 25 | /// April beacon broadcast type definition 26 | typedef NS_ENUM(NSInteger, ABBroadcastType) { 27 | /** Default broadcast type */ 28 | ABBeaconBroadcastiBeacon, 29 | /** Google Eddystone Uid type */ 30 | ABBeaconBroadcastEddystoneUid, 31 | /** Google Eddystone URL type */ 32 | ABBeaconBroadcastEddystoneURL 33 | }; 34 | 35 | /** 36 | * callback method. 37 | * 38 | * @param error nil or specific error. 39 | */ 40 | typedef void(^ABCompletionBlock)(NSError* error); 41 | 42 | -------------------------------------------------------------------------------- /AprilSDK/Headers/ABError.h: -------------------------------------------------------------------------------- 1 | // 2 | // ABError.h 3 | // AprilBeaconSDK 4 | // 5 | // Created by liaojinhua on 15/3/13. 6 | // Copyright (c) 2015年 li shuai. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | /// April Beacon Error Domain 12 | extern NSString * const ABErrorDomain; 13 | 14 | /// April Beacon Error Info Key 15 | extern NSString * const ABErrorInfoKey; 16 | 17 | /// Error message 18 | extern NSString * const ABErrorNotConnectedString; 19 | 20 | /// April Beacon Error Definition 21 | typedef NS_ENUM(NSInteger, ABError) { 22 | /** Unknown error */ 23 | ABErrorUnknown = 0, 24 | /** Value of parameter is not valid */ 25 | ABErrorInvalidParameters = 1, 26 | /** Can't write data when Beacon is not connected */ 27 | ABErrorNotConnected = 2, 28 | }; -------------------------------------------------------------------------------- /AprilSDK/Headers/ABSensor.h: -------------------------------------------------------------------------------- 1 | // 2 | // ABSensor.h 3 | // AprilBeaconSDK 4 | // 5 | // Created by liaojinhua on 14-7-1. 6 | // Copyright (c) 2014年 li shuai. All rights reserved. 7 | // 8 | 9 | #import "ABBeacon.h" 10 | 11 | /** 12 | * ABAcceleration 13 | * 14 | * Discussion: 15 | * A structure containing 3-axis acceleration data. 16 | * 17 | * Fields: 18 | * x: 19 | * X-axis acceleration in G's. 20 | * y: 21 | * Y-axis acceleration in G's. 22 | * z: 23 | * Z-axis acceleration in G's. 24 | */ 25 | typedef struct { 26 | double x; 27 | double y; 28 | double z; 29 | } ABAcceleration; 30 | 31 | /** 32 | * Accelerometer value callback method. 33 | * 34 | * @param acceleration @see ABAcceleration 35 | */ 36 | typedef void(^ABAccValueChangedBlock)(ABAcceleration acceleration); 37 | 38 | /** 39 | * Light value callback method. 40 | * 41 | * @param light value. 42 | */ 43 | typedef void(^ABLightValueChangedBlock)(double light); 44 | 45 | 46 | @interface ABSensor : ABBeacon 47 | /** 48 | * Turn on/off accelerometer. 49 | * Accelerometer is on default 50 | * 51 | * @param on status of accelerometer 52 | * @param completion block handling operation completion 53 | * 54 | * @return void 55 | */ 56 | - (void)setAccelerometerOn:(BOOL)on WithCompletion:(ABCompletionBlock)completion; 57 | 58 | 59 | /** 60 | * Turn on/off light sensor. 61 | * Light sensor is on default 62 | * 63 | * @param on status of light sensor 64 | * @param completion block handling operation completion 65 | * 66 | * @return void 67 | */ 68 | - (void)setLightSensorOn:(BOOL)on WithCompletion:(ABCompletionBlock)completion; 69 | 70 | /** 71 | * Set block to receive acc value changed 72 | * 73 | * @param block the block to callback when value changed 74 | * 75 | * @return void 76 | */ 77 | - (void)setAccValueChangedBlock:(ABAccValueChangedBlock)block; 78 | 79 | /** 80 | * Set block to receive light value changed 81 | * 82 | * @param block the block to callback when value changed 83 | * 84 | * @return void 85 | */ 86 | - (void)setLightValueChangedBlock:(ABLightValueChangedBlock)block; 87 | 88 | 89 | @end 90 | -------------------------------------------------------------------------------- /AprilSDK/Headers/AprilBeaconSDK.h: -------------------------------------------------------------------------------- 1 | // 2 | // AprilBeaconSDK.h 3 | // AprilBeaconSDK 4 | // 5 | // Created by AprilBrother LLC on 14-4-1. 6 | // Copyright (c) 2014年 AprilBrother LLC. All rights reserved. 7 | // version 2.0.5 8 | 9 | #import "ABBeaconManager.h" 10 | #import "ABBluetoothManager.h" 11 | #import "ABBeaconRegion.h" 12 | #import "ABBeacon.h" 13 | #import "ABSensor.h" -------------------------------------------------------------------------------- /AprilSDK/libAprilBeaconSDK.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AprilBrother/AprilBeacon-iOS-SDK/6b558be7052c58e739e8eeb7e33411c95598f435/AprilSDK/libAprilBeaconSDK.a -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 1.0.0(Oct 20, 2015) 2 | Features: 3 | 4 | * Support Google Eddystone protocol 5 | * New update parameters method 6 | * Different Class for discover iBeacons and modify parameters 7 | 8 | 9 | ## 1.3.0(Mar 19, 2015) 10 | Features: 11 | 12 | * Add a method to modify all values of iBeacon. 13 | * If you set password parameter to nil, it will use the default password AprilBrother to replace. 14 | * Add custom error definitions 15 | * Adjust writing logic. 16 | 17 | Bug fixes: 18 | 19 | * Writing failed 20 | * Wrong connect state 21 | 22 | ## 1.2.4 (Oct 22, 2014) 23 | Features: 24 | 25 | * Support iPhone 5s, iPhone 6, iPhone 6 plus simulator build 26 | 27 | ## 1.2.3 (Oct 10, 2014) 28 | Features: 29 | 30 | * iOS 8 support 31 | 32 | ## 1.2.2 (Sep 22, 2014) 33 | Bug fixes: 34 | 35 | * Build error in xocde 5 36 | 37 | ## 1.2.1 (Sep 15, 2014) 38 | Bug fixes: 39 | 40 | * Remove all beacons when start discover 41 | * Issue that can't remove custom filter name 42 | 43 | ## 1.2.0 (Sep 10, 2014) 44 | Feature: 45 | 46 | * Return acceleration value of the accelerometer sensor 47 | 48 | Optimize: 49 | 50 | * Merge connection callback method to one 51 | 52 | Bug fixes: 53 | 54 | * Can not get callback when beacon connected 55 | 56 | ## 1.1.7 (Sep 1, 2014) 57 | Buf fixes: 58 | 59 | * Clean stored beacons when stop discovery 60 | 61 | ## 1.1.6 (Aug 26, 2014) 62 | Buf fixes: 63 | 64 | * Can't callback when connected 65 | 66 | ## 1.1.5 (Aug 15, 2014) 67 | Optimize: 68 | 69 | * Update sensor value more stable 70 | 71 | ## 1.1.4 (Aug 11, 2014) 72 | Bug fixes: 73 | 74 | * Modify UUID failed in iOS8 75 | 76 | ## 1.1.3 (July 27, 2014) 77 | Features: 78 | 79 | * Add modelNumber property to ABBeacon 80 | 81 | ## 1.1.2 (July 23, 2014) 82 | Bug fixes: 83 | 84 | * Multi callback when connected 85 | * Modify tx power failed 86 | 87 | ## 1.1.1 (July 22, 2014) 88 | Features: 89 | 90 | * Add firmwareRevision and manufacturerName property to ABBeacon 91 | * Add custom filter to ABBeaconManager. developer can find his own beacon with specified prefix name. 92 | 93 | ## 1.1.0 (July 3, 2014) 94 | Features: 95 | 96 | * Add sensor apis 97 | 98 | Bugfixes: 99 | 100 | * Fix can't scan april beacons when connect to a beacon 101 | 102 | ## 1.0.3 (June 23, 2014) 103 | Features: 104 | 105 | * Support more April beacons 106 | 107 | Improvment 108 | 109 | * Lazy alloc of object 110 | 111 | Bugfixes: 112 | 113 | * Bug fix 114 | 115 | ## 1.0.2 (May 23, 2014) 116 | Features: 117 | 118 | * Change writeBeaconPassword method to authBeaconWithPassword 119 | 120 | Bugfixes: 121 | 122 | * Read value crash on iOS 7.0 123 | * Error handle of peripheral actions 124 | 125 | ## 1.0.1 (May 19, 2014) 126 | Features: 127 | 128 | * Add auth and reset beacon method to ABBeacon 129 | 130 | ## 1.0.0 (May 8, 2014) 131 | 132 | Features: 133 | 134 | * Ranging and monitoring April beacons 135 | * Beacon connection support 136 | * Read/Write of Major, Minor, Power and Fequency -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | T License (MIT) 2 | 3 | Copyright (c) 2013 Aprbrother, Inc. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | ## Docs 3 | 4 | * [Current documentation](//aprilbrother.github.io/aprilbeacon-ios-sdk/Documents/index.html) 5 | * [Community for AprilBeacon](http://bbs.aprbrother.com) 6 | 7 | ## How to install 8 | 9 | ### From CocoaPods 10 | 11 | Add the following line to your Podfile: 12 | 13 | pod 'AprilSDK' 14 | 15 | 16 | Then run the following command in the same directory as your Podfile: 17 | 18 | pod update 19 | 20 | 21 | ### Normal way 22 | 23 | 1. Copy the folder 'AprilSDK' to your project directory. 24 | 2. Add libAprilBeaconSDK.a to your Framework. 25 | 3. Add 'AprilSDK/Headers' (relative path to your project) to Header Search Paths in Build Settings of your target. 26 | 27 | ### iOS 8 28 | 29 | If your app supports iOS 8, you should add NSLocationAlwaysUsageDescription key with message to be displayed in the prompt to Info.plist. 30 | 31 | ### Project Setting 32 | 33 | Change the value of Build Active Architecture Only to "NO" of your project in Building Settings. 34 | If your proejct is crash, try to add -all_load to Other Linker Flags in Building Settings. 35 | 36 | 37 | ## Changelog 38 | 39 | To see what has changed in recent versions of April SDK, see the [CHANGELOG](https://github.com/AprilBrother/AprilBeacon-iOS-SDK/blob/master/CHANGELOG.md). 40 | --------------------------------------------------------------------------------