Skip to content

Commit

Permalink
Added a fliclib wrapper that can be imported if you want to build for…
Browse files Browse the repository at this point in the history
… simulator
  • Loading branch information
AntonMeier committed May 18, 2016
1 parent 297ad96 commit 05a8260
Show file tree
Hide file tree
Showing 7 changed files with 366 additions and 1 deletion.
14 changes: 13 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,16 @@ The fliclib framework for iOS.
This framework works in collaboration with the Flic app so please make sure that you have it installed before you begin.

Notice: The instructions and documentation available at our website have not been updated to work with the latest release of the framework. This will be done soon.
For instructions on how to implement this go to https://flic.io/partners/developers/ios-tutorial, or take a look at one of our example projects here on github.
For instructions on how to implement this go to https://flic.io/partners/developers/ios-tutorial, or take a look at one of our example projects here on github.

**Simulator Support**

The framework itself does not contain slices for x86 and i386 (iOS Simulator). The reason for this is that if we were to add those slices to the framework then
they would have to be removed before App Store submission, which is not a very straightforward thing to do. So, for those who want to run the framework in the simulator
we instead provide a wrapper that adds a fake fliclib implementation when building for x86 and i386.

To use this wrapper follow these steps:

1. Include the files inside the `simulator-wrapper` folder to your project.
2. On all the places in your code where you need to import fliclib you should import the wrapper instead. In other words, replace `#import <fliclib/fliclib.h>` with `#import "fliclibWrapper.h"`. Of course, the file path will depend on how you have configured your project. For example, if you have the *fliclib-ios* repository as a git submodule in your project root then it might look like this `#import "../fliclib-ios/simulator-wrapper/fliclibWrapper.h"`.
3. Make sure that both `SCLFlicManagerSimulator.m` and `SCLFlicButtonSimulator.m` are added to *Compile Sources* in your project *Build Phases*.
Binary file added simulator-wrapper/.DS_Store
Binary file not shown.
102 changes: 102 additions & 0 deletions simulator-wrapper/SCLFlicButtonSimulator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
//
// @file SCLFlicButtonSimulator.h
// @framework fliclib
//
// Created by Anton Meier on 2016-06-17.
// Copyright (c) 2016 Shortcut Labs. All rights reserved.
//

#import <Foundation/Foundation.h>
@class UIColor;

typedef NS_ENUM(NSInteger, SCLFlicButtonConnectionState) {
SCLFlicButtonConnectionStateConnected = 0,
SCLFlicButtonConnectionStateConnecting,
SCLFlicButtonConnectionStateDisconnected,
SCLFlicButtonConnectionStateDisconnecting,
};

typedef NS_ENUM(NSInteger, SCLFlicButtonLEDIndicateCount) {
SCLFlicButtonLEDIndicateCount1 = 1,
SCLFlicButtonLEDIndicateCount2,
SCLFlicButtonLEDIndicateCount3,
SCLFlicButtonLEDIndicateCount4,
SCLFlicButtonLEDIndicateCount5,
};

typedef NS_ENUM(NSInteger, SCLFlicButtonTriggerBehavior) {
SCLFlicButtonTriggerBehaviorClickAndHold = 0,
SCLFlicButtonTriggerBehaviorClickAndDoubleClick,
SCLFlicButtonTriggerBehaviorClickAndDoubleClickAndHold,
};

typedef NS_ENUM(NSInteger, SCLFlicError) {
SCLFlicErrorUnknown = 0,
SCLFlicErrorCouldNotCompleteTask = 1,
SCLFlicErrorConnectionFailed = 2,
SCLFlicErrorCouldNotUpdateRSSI = 3,
SCLFlicErrorButtonIsPrivate = 10,
SCLFlicErrorCryptographicFailure = 11,
SCLFlicErrorMissingData = 13,
SCLFlicErrorInvalidSignature = 14,
SCLFlicErrorButtonAlreadyGrabbed = 15,
SCLFlicErrorBluetoothErrorUnknown = 100,
SCLFlicErrorBluetoothErrorInvalidParameters = 101,
SCLFlicErrorBluetoothErrorInvalidHandle = 102,
SCLFlicErrorBluetoothErrorNotConnected = 103,
SCLFlicErrorBluetoothErrorOutOfSpace = 104,
SCLFlicErrorBluetoothErrorOperationCancelled = 105,
SCLFlicErrorBluetoothErrorConnectionLost = 106,
SCLFlicErrorBluetoothErrorPeripheralDisconnected = 107,
SCLFlicErrorBluetoothErrorUUIDNotAllowed = 108,
SCLFlicErrorBluetoothErrorAlreadyAdvertising = 109,
SCLFlicErrorBluetoothErrorConnectionFailed = 110,
SCLFlicErrorBluetoothErrorConnectionLimitReached = 111,
SCLFlicErrorFlicRefusedConnection = 200,
};

@protocol SCLFlicButtonDelegate;

@interface SCLFlicButton : NSObject {

}

@property(weak, nonatomic, nullable) id<SCLFlicButtonDelegate> delegate;
@property (readonly, nonatomic, strong, nonnull) NSUUID *buttonIdentifier;
@property (readonly, nonatomic, strong, nonnull) NSString *buttonPublicKey;
@property (atomic, readonly, strong, nonnull) NSString *name;
@property (atomic, readonly, strong, nonnull) UIColor *color;
@property (atomic, readonly, strong, nonnull) NSString *userAssignedName;
@property (atomic, readonly) SCLFlicButtonConnectionState connectionState;
@property (nonatomic, readwrite) BOOL lowLatency;
@property (nonatomic, readwrite) SCLFlicButtonTriggerBehavior triggerBehavior;
@property (nonatomic, readonly) int pressCount;
@property (readonly) BOOL isReady;


- (void) connect;
- (void) disconnect;
- (void) indicateLED: (SCLFlicButtonLEDIndicateCount) count;
- (void) readRSSI;

@end

@protocol SCLFlicButtonDelegate <NSObject>

@required

@optional

- (void) flicButton:(SCLFlicButton * _Nonnull) button didReceiveButtonDown:(BOOL) queued age: (NSInteger) age;
- (void) flicButton:(SCLFlicButton * _Nonnull) button didReceiveButtonUp:(BOOL) queued age: (NSInteger) age;
- (void) flicButton:(SCLFlicButton * _Nonnull) button didReceiveButtonClick:(BOOL) queued age: (NSInteger) age;
- (void) flicButton:(SCLFlicButton * _Nonnull) button didReceiveButtonDoubleClick:(BOOL) queued age: (NSInteger) age;
- (void) flicButton:(SCLFlicButton * _Nonnull) button didReceiveButtonHold:(BOOL) queued age: (NSInteger) age;
- (void) flicButtonDidConnect:(SCLFlicButton * _Nonnull) button;
- (void) flicButtonIsReady:(SCLFlicButton * _Nonnull) button;
- (void) flicButton:(SCLFlicButton * _Nonnull) button didDisconnectWithError:(NSError * _Nullable) error;
- (void) flicButton:(SCLFlicButton * _Nonnull) button didFailToConnectWithError:(NSError * _Nullable) error;
- (void) flicButton:(SCLFlicButton * _Nonnull) button didUpdateRSSI:(NSNumber * _Nonnull) RSSI error:(NSError * _Nullable) error;

@end

76 changes: 76 additions & 0 deletions simulator-wrapper/SCLFlicButtonSimulator.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
//
// @file SCLFlicButtonSimulator.m
// @framework fliclib
//
// Created by Anton Meier on 2016-06-17.
// Copyright (c) 2016 Shortcut Labs. All rights reserved.
//

#import "SCLFlicButtonSimulator.h"
#if TARGET_OS_SIMULATOR

#import <UIKit/UIKit.h>

@implementation SCLFlicButton

- (instancetype) init {
self = [super init];
if ( self != nil ) {
NSLog(@"SCLFlicButtonSimulator init");
_isReady = YES;
_lowLatency = NO;
_buttonIdentifier = [NSUUID UUID];
_name=[NSString stringWithFormat:@"FLIC: %@", _buttonIdentifier.UUIDString ];
_connectionState=SCLFlicButtonConnectionStateConnected;
_triggerBehavior = SCLFlicButtonTriggerBehaviorClickAndHold;
_pressCount = 0;
_buttonPublicKey = _buttonIdentifier.UUIDString;
_userAssignedName = @"My Flic";
_color = [UIColor whiteColor];

// Uncomment to recieve a button down 2 seconds after grab.
/*
__weak SCLFlicButton *flicButton = self;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
if ([flicButton.delegate respondsToSelector:@selector(flicButton:didReceiveButtonDown:age:)]) {
dispatch_async(dispatch_get_main_queue(), ^{ [flicButton.delegate flicButton:self didReceiveButtonDown:NO age:0]; });
}
});
*/
return self;
}
return nil;
}

- (void) connect {
_connectionState = SCLFlicButtonConnectionStateConnected;
if ([self.delegate respondsToSelector:@selector(flicButtonDidConnect:)]) {
dispatch_async(dispatch_get_main_queue(), ^{ [self.delegate flicButtonDidConnect:self]; });
}
_isReady = YES;
if ([self.delegate respondsToSelector:@selector(flicButtonIsReady:)]) {
dispatch_async(dispatch_get_main_queue(), ^{ [self.delegate flicButtonIsReady:self]; });
}
}

- (void) disconnect {
_connectionState = SCLFlicButtonConnectionStateConnected;
_isReady = NO;
if ([self.delegate respondsToSelector:@selector(flicButton:didDisconnectWithError:)]) {
dispatch_async(dispatch_get_main_queue(), ^{ [self.delegate flicButton:self didDisconnectWithError:nil]; });
}
}

- (void) indicateLED: (SCLFlicButtonLEDIndicateCount) count {

}

- (void) readRSSI {
if ([self.delegate respondsToSelector:@selector(flicButton:didUpdateRSSI:error:)]) {
dispatch_async(dispatch_get_main_queue(), ^{ [self.delegate flicButton:self didUpdateRSSI:[NSNumber numberWithInt: -1] error:nil]; });
}
}

@end

#endif
57 changes: 57 additions & 0 deletions simulator-wrapper/SCLFlicManagerSimulator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
//
// @file SCLFlicManagerSimulator.h
// @framework fliclib
//
// Created by Anton Meier on 2016-05-17.
// Copyright (c) 2016 Shortcut Labs. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "SCLFlicButtonSimulator.h"

typedef NS_ENUM(NSInteger, SCLFlicManagerBluetoothState) {
SCLFlicManagerBluetoothStatePoweredOn = 0,
SCLFlicManagerBluetoothStatePoweredOff,
SCLFlicManagerBluetoothStateResetting,
SCLFlicManagerBluetoothStateUnsupported,
SCLFlicManagerBluetoothStateUnauthorized,
SCLFlicManagerBluetoothStateUnknown,
};

@protocol SCLFlicManagerDelegate;

@interface SCLFlicManager : NSObject {

}

@property(weak, nonatomic, nullable) id<SCLFlicManagerDelegate> delegate;
@property(weak, nonatomic, nullable) id<SCLFlicButtonDelegate> defaultButtonDelegate;
@property (nonatomic, readonly) SCLFlicManagerBluetoothState bluetoothState;
@property (readonly, getter=isEnabled) BOOL enabled;

+ (instancetype _Nullable) sharedManager;
+ (instancetype _Nullable) configureWithDelegate:(id<SCLFlicManagerDelegate> _Nullable) delegate defaultButtonDelegate: (id<SCLFlicButtonDelegate> _Nullable) buttonDelegate appID: (NSString * _Nonnull) appID appSecret: (NSString * _Nonnull) appSecret backgroundExecution: (BOOL) bExecution;
- (NSDictionary<NSUUID *, SCLFlicButton *> * _Nonnull) knownButtons;
- (void) forgetButton:(SCLFlicButton * _Nonnull) button;
- (void) disable;
- (void) enable;
- (void) grabFlicFromFlicAppWithCallbackUrlScheme: (NSString * _Nonnull) scheme;
- (BOOL) handleOpenURL: (NSURL * _Nonnull) url;
- (void) onLocationChange;

@end


@protocol SCLFlicManagerDelegate <NSObject>

@required

- (void) flicManager:(SCLFlicManager * _Nonnull) manager didGrabFlicButton:(SCLFlicButton * _Nullable) button withError: (NSError * _Nullable) error;

@optional

- (void) flicManager:(SCLFlicManager * _Nonnull) manager didChangeBluetoothState: (SCLFlicManagerBluetoothState) state;
- (void) flicManagerDidRestoreState:(SCLFlicManager * _Nonnull) manager;
- (void) flicManager:(SCLFlicManager * _Nonnull) manager didForgetButton:(NSUUID * _Nonnull) buttonIdentifier error:(NSError * _Nullable)error;

@end
101 changes: 101 additions & 0 deletions simulator-wrapper/SCLFlicManagerSimulator.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
//
// @file SCLFlicManagerSimulator.m
// @framework fliclib
//
// Created by Anton Meier on 2016-05-17.
// Copyright (c) 2016 Shortcut Labs. All rights reserved.
//

#import "SCLFlicManagerSimulator.h"
#if TARGET_OS_SIMULATOR

@interface SCLFlicManager ()

@property (nonatomic, strong) NSMutableDictionary<NSUUID *, SCLFlicButton *> *buttonDictionary;

@end

@interface SCLFlicButton ()

- (instancetype) init;

@end

@implementation SCLFlicManager

static SCLFlicManager *_sharedManager = nil;

+ (SCLFlicManager *) sharedManager; {
return _sharedManager;
}

+ (instancetype _Nullable) configureWithDelegate:(id<SCLFlicManagerDelegate> _Nullable) delegate defaultButtonDelegate: (id<SCLFlicButtonDelegate> _Nullable) buttonDelegate appID: (NSString * _Nonnull) appID appSecret: (NSString * _Nonnull) appSecret backgroundExecution: (BOOL) bExecution; {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_sharedManager = [[SCLFlicManager alloc] initWithDelegate:delegate buttonDelegate:buttonDelegate];
if ([SCLFlicManager sharedManager].delegate && [[SCLFlicManager sharedManager].delegate respondsToSelector:@selector(flicManagerDidRestoreState:)]) {
dispatch_async(dispatch_get_main_queue(), ^{ [[SCLFlicManager sharedManager].delegate flicManagerDidRestoreState:[SCLFlicManager sharedManager]]; });
}
if ([SCLFlicManager sharedManager].delegate && [[SCLFlicManager sharedManager].delegate respondsToSelector:@selector(flicManager:didChangeBluetoothState:)]) {
dispatch_async(dispatch_get_main_queue(), ^{ [[SCLFlicManager sharedManager].delegate flicManager:[SCLFlicManager sharedManager] didChangeBluetoothState:[SCLFlicManager sharedManager].bluetoothState]; });
}
});

return _sharedManager;
}

- (instancetype) initWithDelegate: (id<SCLFlicManagerDelegate> _Nullable) delegate buttonDelegate: (id<SCLFlicButtonDelegate> _Nullable) buttonDelegate {
self = [super init];
if ( self != nil ) {
NSLog(@"SCLFlicManagerSimulator init");
_enabled = YES;
_delegate = delegate;
_buttonDictionary = [NSMutableDictionary dictionary];
_defaultButtonDelegate = buttonDelegate;
_bluetoothState = SCLFlicManagerBluetoothStatePoweredOn;
return self;
}
return nil;
}

- (void) forgetButton:(SCLFlicButton *) button {
if ([self.buttonDictionary objectForKey:button.buttonIdentifier]) {
[self.buttonDictionary removeObjectForKey:button.buttonIdentifier];
if (self.delegate && [self.delegate respondsToSelector:@selector(flicManager:didForgetButton:error:)]) {
dispatch_async(dispatch_get_main_queue(), ^{ [self.delegate flicManager:self didForgetButton:button.buttonIdentifier error:nil]; });
}
}
}

- (void) disable {
_enabled = NO;
}

- (void) enable {
_enabled = YES;
}

- (NSDictionary*) knownButtons {
return [self.buttonDictionary copy];
}

- (void) onLocationChange {

}

- (BOOL) handleOpenURL: (NSURL * _Nonnull) url; {
return YES;
}

- (void) grabFlicFromFlicAppWithCallbackUrlScheme: (NSString *) scheme {
SCLFlicButton *button = [[SCLFlicButton alloc] init];
button.delegate = self.defaultButtonDelegate;
[self.buttonDictionary setObject:button forKey:button.buttonIdentifier];
if (self.delegate && [self.delegate respondsToSelector:@selector(flicManager:didGrabFlicButton:withError:)]) {
dispatch_async(dispatch_get_main_queue(), ^{ [self.delegate flicManager:self didGrabFlicButton:button withError:nil]; });
}
}

@end

#endif
17 changes: 17 additions & 0 deletions simulator-wrapper/fliclibWrapper.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//
// fliclibWrapper.h
// fliclib
//
// Created by Anton Meier on 2016-04-20.
// Copyright (c) 2016 Shortcut Labs. All rights reserved.
//

#if TARGET_OS_SIMULATOR

#import "SCLFlicManagerSimulator.h"

#else

#import <fliclib/fliclib.h>

#endif

0 comments on commit 05a8260

Please sign in to comment.