diff --git a/Lighthouse/LighthouseManager.h b/Lighthouse/LighthouseManager.h index d1d3c17..13fb2b1 100644 --- a/Lighthouse/LighthouseManager.h +++ b/Lighthouse/LighthouseManager.h @@ -39,6 +39,7 @@ typedef void (^SubscribeBlock)(id self, NSDictionary *data); - (void)activate; - (void)suspend; - (void)terminate; +- (void)unload; #pragma mark - Properties - (void)setProperties:(NSDictionary *)properties; @@ -57,6 +58,10 @@ typedef void (^SubscribeBlock)(id self, NSDictionary *data); + (void)enableLogging; + (BOOL)isLoggingEnabled; +#pragma mark - Bluetooth +- (void)promptBluetooth; +- (BOOL)isBluetoothOn; + #pragma mark - Settings - (NSDictionary *)settings; diff --git a/Lighthouse/libLighthouse.a b/Lighthouse/libLighthouse.a index 1720bd3..4e3116b 100644 Binary files a/Lighthouse/libLighthouse.a and b/Lighthouse/libLighthouse.a differ diff --git a/LighthouseExample/LighthouseExample.xcodeproj/project.pbxproj b/LighthouseExample/LighthouseExample.xcodeproj/project.pbxproj index 4884395..bd8bbd4 100644 --- a/LighthouseExample/LighthouseExample.xcodeproj/project.pbxproj +++ b/LighthouseExample/LighthouseExample.xcodeproj/project.pbxproj @@ -276,6 +276,7 @@ ); OTHER_LDFLAGS = "-ObjC"; PRODUCT_NAME = "$(TARGET_NAME)"; + VALID_ARCHS = "armv7 armv6 arm64 i386"; WRAPPER_EXTENSION = app; }; name = Debug; @@ -295,6 +296,7 @@ ); OTHER_LDFLAGS = "-ObjC"; PRODUCT_NAME = "$(TARGET_NAME)"; + VALID_ARCHS = "armv7 armv6 arm64 i386"; WRAPPER_EXTENSION = app; }; name = Release; diff --git a/LighthouseExample/LighthouseExample/AppDelegate.m b/LighthouseExample/LighthouseExample/AppDelegate.m index 0302d88..58b6efd 100644 --- a/LighthouseExample/LighthouseExample/AppDelegate.m +++ b/LighthouseExample/LighthouseExample/AppDelegate.m @@ -47,11 +47,21 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( [NSTimer scheduledTimerWithTimeInterval:5 target:[LighthouseManager sharedInstance] selector:@selector(requestPermission) userInfo:nil repeats:NO]; + // Request bluetooth permission (you can do this whenever you like - it will ask user to turn on bluetooth if they haven't already - possibly you want to wait until they reach a certain section of your app) + // To fire immediately + // [[LighthouseManager sharedInstance] promptBluetooth]; + // In this example we have delayed the permission request by 15 seconds + // You can also check if they have bluetooth enabled already by checking the return BOOL value of [[LighthouseManager sharedInstance] isBluetoothOn]; + [NSTimer scheduledTimerWithTimeInterval:15 target:[LighthouseManager sharedInstance] selector:@selector(promptBluetooth) userInfo:nil repeats:NO]; + + // Request push notification permission (you can do this whenever you like - it will ask user for push notification permission - possibly you want to wait until they reach a certain section of your app) // To fire immediately // [[LighthouseManager sharedInstance] requestPushNotifications]; // In this example we have delayed the permission request by 15 seconds - [NSTimer scheduledTimerWithTimeInterval:15 target:[LighthouseManager sharedInstance] selector:@selector(requestPushNotifications) userInfo:nil repeats:NO]; + // You can check if they have already given push notification permission by checking the length of [[LighthouseManager sharedInstance] pushNotificationToken]; is greater than 0 + [NSTimer scheduledTimerWithTimeInterval:30 target:[LighthouseManager sharedInstance] selector:@selector(requestPushNotifications) userInfo:nil repeats:NO]; + // Listen to notifications from Lighthouse [[LighthouseManager sharedInstance] subscribe:@"LighthouseDidEnterBeacon" observer:self selector:@selector(didEnterBeacon:)]; @@ -92,14 +102,18 @@ - (void)applicationWillTerminate:(UIApplication *)application { - (void)didEnterBeacon:(NSDictionary *)data { NSLog(@"didEnterBeacon %@", data); + // Show message with format "Enter: UUID-Major-Minor" + [self triggerLocalNotification:[NSString stringWithFormat:@"Enter: %@", data[@"key"]]]; } - (void)didExitBeacon:(NSDictionary *)data { NSLog(@"didExitBeacon %@", data); + // Show message with format "Exit: UUID-Major-Minor" + [self triggerLocalNotification:[NSString stringWithFormat:@"Exit: %@", data[@"key"]]]; } - (void)didRangeBeacon:(NSDictionary *)data { - NSLog(@"didRangeBeacon %@", data); + //NSLog(@"didRangeBeacon %@", data); } - (void)didReceiveNotification:(NSDictionary *)data { @@ -116,15 +130,35 @@ - (void)didReceiveCampaign:(NSDictionary *)data { // You can then trigger a "campaign action" when the user clicks a button for instance to record how many people // have see and performed an action on the campaign. For the moment we just wait 15 seconds before triggering [NSTimer scheduledTimerWithTimeInterval:15 target:[LighthouseManager sharedInstance] selector:@selector(campaignActioned:) userInfo:data repeats:NO]; - - NSDictionary *notification = [[[LighthouseManager sharedInstance] notifications] lastObject]; - [[LighthouseManager sharedInstance] campaignActioned:notification]; + + // Often you will want to retrieve and action the last notification you received + // NSDictionary *notification = [[[LighthouseManager sharedInstance] notifications] lastObject]; + // [[LighthouseManager sharedInstance] campaignActioned:notification]; } - (void)didUpdateSettings:(NSDictionary *)data { NSLog(@"didUpdateSettings %@", data); } +- (void)triggerLocalNotification:(NSString *)text { + UILocalNotification *notification = [[UILocalNotification alloc] init]; + notification.alertBody = text; + notification.fireDate = [[NSDate alloc] initWithTimeIntervalSinceNow:0]; + notification.timeZone = [NSTimeZone defaultTimeZone]; + notification.repeatInterval = 0; + notification.soundName = UILocalNotificationDefaultSoundName; + [[UIApplication sharedApplication] presentLocalNotificationNow:notification]; +} + +- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification { + UIApplicationState applicationState = application.applicationState; + if (applicationState == UIApplicationStateBackground) { + [application presentLocalNotificationNow:notification]; + } else { + [[[UIAlertView alloc] initWithTitle:@"Beacon" message:notification.alertBody delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show]; + } +} + #pragma mark - Push Notifications - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo { diff --git a/LighthouseExample/LighthouseExample/Images.xcassets/AppIcon.appiconset/Contents.json b/LighthouseExample/LighthouseExample/Images.xcassets/AppIcon.appiconset/Contents.json index 91bf9c1..b7f3352 100644 --- a/LighthouseExample/LighthouseExample/Images.xcassets/AppIcon.appiconset/Contents.json +++ b/LighthouseExample/LighthouseExample/Images.xcassets/AppIcon.appiconset/Contents.json @@ -15,6 +15,11 @@ "size" : "60x60", "scale" : "2x" }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, { "idiom" : "ipad", "size" : "29x29", diff --git a/LighthouseExample/LighthouseExample/LighthouseExample-Info.plist b/LighthouseExample/LighthouseExample/LighthouseExample-Info.plist index fac9b4b..5dc1fc1 100644 --- a/LighthouseExample/LighthouseExample/LighthouseExample-Info.plist +++ b/LighthouseExample/LighthouseExample/LighthouseExample-Info.plist @@ -38,6 +38,7 @@ location bluetooth-central + remote-notification NSLocationAlwaysUsageDescription We need to scan beacons in background. You can customise this message in the Info plist. diff --git a/README.md b/README.md index 5d72fb2..4937b15 100644 --- a/README.md +++ b/README.md @@ -5,11 +5,17 @@ The Lighthouse iOS SDK is designed to be simple to develop with, allowing you to ## Supported iOS Versions -As Lighthouse relies on iBeacon support the SDK only performs functionality on iOS 7 (see supported devices http://support.apple.com/kb/HT6048). However the SDK still runs on iOS 6 apps but performs a graceful silent fallback. Any requests to the SDK will be ignored, you can even check whether the app supports beacons using "- (BOOL)doesDeviceSupportBeacons;" method. +As Lighthouse relies on iBeacon support the SDK only performs functionality on iOS 7 (see supported devices http://support.apple.com/kb/HT6048). However the SDK still runs on iOS 5.1 and above apps but performs a graceful silent fallback. Any requests to the SDK will be ignored, you can even check whether the app supports beacons using "- (BOOL)doesDeviceSupportBeacons;" method. + +## SDK Specs + +Valid Architectures: armv7 armv7s i386 arm64 +Minimum iOS Deployment Target: 5.1 +Base SDK support: iOS 8 ## Install Guide -Installing the client should be a breeze. If it's not, please let us know at [team@lighthousebeacon.io](mailto:team@lighthousebeacon.io) +Installing the client should be straight forward. If it's not, please let us know at [team@lighthousebeacon.io](mailto:team@lighthousebeacon.io) ### Universal Library @@ -24,13 +30,7 @@ Within the folder called "Lighthouse" should be the following contents: - Lighthouse.h ### Add Files to Xcode -Just drag the Lighthouse folder into your Xcode project. - -### Add Required Frameworks -Go into your app's target’s Build Phases screen and add the following (if they don't already exist) to the "Link Binary With Libraries" section. - -- CoreLocation.framework -- CoreBluetooth.framework +Just drag the Lighthouse folder which includes those 2 files into your Xcode project. ### Build Settings Under your application targets "Build Settings" configuration find the "Other Linker Flags" property and set it to "-ObjC". @@ -41,17 +41,16 @@ You'll need to import the LighthouseManager.h header into the files that contain #import "LighthouseManager.h" ### Add Background Modes -In your application plist file (often called "ApplicationName-Info.plist") add a row for -"Required background modes" of type Array. It then needs: +In your application plist file (often called "ApplicationName-Info.plist") add a row for "Required background modes" of type Array. It then needs: - "App registers for location updates" +- "App downloads content in response to push notifications" - "App communicates using CoreBluetooth" -These are needed to receive the background beacon notifications. - -To support updates in iOS 8 you need to add a string to the plist as well. This describes why your app needs location. +To support updates in iOS 8 you need to add the following Cocoa Keys to the plist. Even for non iOS 8 apps its good practice to include these. They describe why your app needs location. - "NSLocationAlwaysUsageDescription" +- "NSLocationUsageDescription" ### Compile Try and compile. It should work! @@ -325,6 +324,15 @@ You can also check whether permission has been requested previously using: [[LighthouseManager sharedInstance] hasRequestedPermission]; +### Prompting Bluetooth +Some users have bluetooth turned off and you might want to prompt them to turn it on. iBeacons depends on bluetooth being on to function and the Lighthouse SDK cannot complete "launch" process without it. We don't want the SDK to prompt users automatically, instead we give you the control to prompt the users at any time (usually introducing the user as to why they'll need bluetooth). Once you prompt the user and if they subsequently turn on bluetooth then the SDK will automatically continue the launch process, if they don't turn on bluetooth then it will remain idle until a future time when they enable it. + + [[LighthouseManager sharedInstance] promptBluetooth]; + +You can also check whether bluetooth is on using the following method. This can be help you decide whether you need to show them an introuction screen about the importance of bluetooth. + + [[LighthouseManager sharedInstance] isBluetoothOn]; + ### Requesting Push Notification Permission Likewise with location permission above you can request push notification permission from a user with the following methods. If your app has already requested permission this will operate silently in the background, it is still important to run them though if you want to receive push notifications for campaigns from the Lighthouse API. @@ -362,7 +370,7 @@ You can also view an array of all notifications received (you could for instance [[LighthouseManager sharedInstance] notifications] -It can also be helpful to have access to the devices push notification token. You can use this in the Admin Integration page to test your push notifications certificates. Just copy/paste the value into the Test Push Notification section and hit send. +It can also be helpful to have access to the devices push notification token. You can use this in the Admin Integration page to test your push notifications certificates. Just copy/paste the value into the Test Push Notification section and hit send. NOTE: this method will return an empty string value if they haven't accepted push notification permission. You can check the length of the string to see whether they accepted or not. [[LighthouseManager sharedInstance] pushNotificationToken] @@ -427,6 +435,20 @@ If a campaign is triggered then a push notification will be sent to the device, ## Changelog +##### 1.7 + ++ Added "(BOOL)isLocationPermissionAuthorized" method to check if location permission has been authorised ++ Added "(BOOL)isBluetoothOn" method to check if bluetooth is enabled ++ Added "(void)promptBluetooth" method to ask user to turn on bluetooth if they haven't already (use in combination with above check) ++ Added "(void)unload" method to completely reset Lighthouse back to factory defaults ++ Improved "launch" method flow with improved logging when a user hasn't enabled location / bluetooth yet. Call launch in your applicationDidLaunch then just ask for permissions when needed. ++ Further updates for iOS 8 support ++ Stability updates ++ Now supports Minimum Deployment Target of 5.1 ++ The distance value for ranged beacons will update faster when in Immediate distance to the beacon, giving a value of 0 rather than relying on RSSI values. ++ Updated installation instructions ++ Updated example application + ##### 1.6 + Update to support iOS 8 "registerForRemoteNotifications" as they have deprecated "registerForRemoteNotificationTypes"