├── sentinel.gif ├── sentinel_rest.gif ├── RBSentinelDemo WatchKit Extension ├── Images.xcassets │ └── README__ignoredByTemplate__ ├── RBSentinelDemo WatchKit Extension.entitlements ├── InterfaceController.h ├── NotificationController.h ├── Supporting Files │ ├── PushNotificationPayload.apns │ └── Info.plist ├── NotificationController.m └── InterfaceController.m ├── RBSentinelDemo.xcodeproj ├── xcuserdata │ └── rsenth.xcuserdatad │ │ ├── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist │ │ └── xcschemes │ │ ├── xcschememanagement.plist │ │ ├── RBSentinelDemo.xcscheme │ │ ├── RBSentinelDemo WatchKit App.xcscheme │ │ └── Notification - RBSentinelDemo WatchKit App.xcscheme ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ └── rsenth.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── project.pbxproj ├── RBSentinelDemo ├── core │ ├── controller │ │ ├── ViewController.h │ │ └── ViewController.m │ ├── handler │ │ ├── PostHandler.h │ │ └── PostHandler.m │ ├── delegate │ │ ├── AppDelegate.h │ │ └── AppDelegate.m │ └── system │ │ ├── Images.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Base.lproj │ │ ├── LaunchScreen.xib │ │ └── Main.storyboard ├── RBSentinelDemo.entitlements └── Supporting Files │ ├── main.m │ └── Info.plist ├── .gitignore ├── RBSentinel.podspec ├── RBSentinelDemoTests ├── Supporting Files │ └── Info.plist └── RBSentinelDemoTests.m ├── LICENSE ├── RBSentinelDemo WatchKit App ├── Supporting Files │ └── Info.plist ├── Images.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json └── Base.lproj │ └── Interface.storyboard ├── RBSentinel ├── RBSentinel.h └── RBSentinel.m └── README.md /sentinel.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoshanNindrai/RBSentinel/HEAD/sentinel.gif -------------------------------------------------------------------------------- /sentinel_rest.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoshanNindrai/RBSentinel/HEAD/sentinel_rest.gif -------------------------------------------------------------------------------- /RBSentinelDemo WatchKit Extension/Images.xcassets/README__ignoredByTemplate__: -------------------------------------------------------------------------------- 1 | Did you know that git does not support storing empty directories? 2 | -------------------------------------------------------------------------------- /RBSentinelDemo.xcodeproj/xcuserdata/rsenth.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /RBSentinelDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /RBSentinelDemo.xcodeproj/project.xcworkspace/xcuserdata/rsenth.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoshanNindrai/RBSentinel/HEAD/RBSentinelDemo.xcodeproj/project.xcworkspace/xcuserdata/rsenth.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /RBSentinelDemo/core/controller/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // RBSentinelDemo 4 | // 5 | // Created by Roshan Nindrai Senthilnathan on 5/24/15. 6 | // Copyright (c) 2015 Roshan Nindrai Senthilnathan. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /RBSentinelDemo/RBSentinelDemo.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.application-groups 6 | 7 | group.sentinel 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | .DS_Store 3 | build/ 4 | *.pbxuser 5 | !default.pbxuser 6 | *.mode1v3 7 | !default.mode1v3 8 | *.mode2v3 9 | !default.mode2v3 10 | *.perspectivev3 11 | !default.perspectivev3 12 | *.xcworkspace 13 | !default.xcworkspace 14 | xcuserdata 15 | profile 16 | *.moved-aside 17 | DerivedData 18 | .idea/ 19 | # Pods - for those of you who use CocoaPods 20 | Pods 21 | -------------------------------------------------------------------------------- /RBSentinelDemo WatchKit Extension/RBSentinelDemo WatchKit Extension.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.application-groups 6 | 7 | group.sentinel 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /RBSentinelDemo/core/handler/PostHandler.h: -------------------------------------------------------------------------------- 1 | // 2 | // PostHandler.h 3 | // RBOxygenDemo 4 | // 5 | // Created by Roshan Balaji Nindrai SenthilNathan on 5/16/15. 6 | // Copyright (c) 2015 Roshan Balaji Nindrai SenthilNathan. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "RBSentinel.h" 11 | 12 | @interface PostHandler : NSObject 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /RBSentinelDemo/core/delegate/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // RBSentinelDemo 4 | // 5 | // Created by Roshan Nindrai Senthilnathan on 5/24/15. 6 | // Copyright (c) 2015 Roshan Nindrai Senthilnathan. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /RBSentinelDemo WatchKit Extension/InterfaceController.h: -------------------------------------------------------------------------------- 1 | // 2 | // InterfaceController.h 3 | // RBSentinelDemo WatchKit Extension 4 | // 5 | // Created by Roshan Nindrai Senthilnathan on 5/24/15. 6 | // Copyright (c) 2015 Roshan Nindrai Senthilnathan. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface InterfaceController : WKInterfaceController 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /RBSentinelDemo WatchKit Extension/NotificationController.h: -------------------------------------------------------------------------------- 1 | // 2 | // NotificationController.h 3 | // RBSentinelDemo WatchKit Extension 4 | // 5 | // Created by Roshan Nindrai Senthilnathan on 5/24/15. 6 | // Copyright (c) 2015 Roshan Nindrai Senthilnathan. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface NotificationController : WKUserNotificationInterfaceController 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /RBSentinelDemo/Supporting Files/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // RBSentinelDemo 4 | // 5 | // Created by Roshan Nindrai Senthilnathan on 5/24/15. 6 | // Copyright (c) 2015 Roshan Nindrai Senthilnathan. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /RBSentinel.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | 3 | s.name = 'RBSentinel' 4 | s.version = '0.1.5' 5 | s.license = 'MIT' 6 | s.platform = :ios, '8.2' 7 | 8 | s.summary = 'RBSentinel improves communication gap between the applewatch and the parent application.' 9 | s.homepage = 'https://github.com/RoshanNindrai/RBSentinel' 10 | s.author = { 'Roshan Balaji' => 'roshan.nindrai@gmail.com'} 11 | s.source = { :git => 'https://github.com/RoshanNindrai/RBSentinel.git', :tag => s.version.to_s } 12 | 13 | s.source_files = 'RBSentinel/RBSentinel.{h,m}' 14 | 15 | s.requires_arc = true 16 | end 17 | -------------------------------------------------------------------------------- /RBSentinelDemo/core/system/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" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /RBSentinelDemoTests/Supporting Files/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | RB.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /RBSentinelDemo WatchKit Extension/Supporting Files/PushNotificationPayload.apns: -------------------------------------------------------------------------------- 1 | { 2 | "aps": { 3 | "alert": { 4 | "body": "Test message", 5 | "title": "Optional title" 6 | }, 7 | "category": "myCategory" 8 | }, 9 | 10 | "WatchKit Simulator Actions": [ 11 | { 12 | "title": "First Button", 13 | "identifier": "firstButtonAction" 14 | } 15 | ], 16 | 17 | "customKey": "Use this file to define a testing payload for your notifications. The aps dictionary specifies the category, alert text and title. The WatchKit Simulator Actions array can provide info for one or more action buttons in addition to the standard Dismiss button. Any other top level keys are custom payload. If you have multiple such JSON files in your project, you'll be able to select them when choosing to debug the notification interface of your Watch App." 18 | } 19 | -------------------------------------------------------------------------------- /RBSentinelDemoTests/RBSentinelDemoTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // RBSentinelDemoTests.m 3 | // RBSentinelDemoTests 4 | // 5 | // Created by Roshan Nindrai Senthilnathan on 5/24/15. 6 | // Copyright (c) 2015 Roshan Nindrai Senthilnathan. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface RBSentinelDemoTests : XCTestCase 13 | 14 | @end 15 | 16 | @implementation RBSentinelDemoTests 17 | 18 | - (void)setUp { 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 | // Put teardown code here. This method is called after the invocation of each test method in the class. 25 | [super tearDown]; 26 | } 27 | 28 | - (void)testExample { 29 | // This is an example of a functional test case. 30 | XCTAssert(YES, @"Pass"); 31 | } 32 | 33 | - (void)testPerformanceExample { 34 | // This is an example of a performance test case. 35 | [self measureBlock:^{ 36 | // Put the code you want to measure the time of here. 37 | }]; 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 RoshanNindrai 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, 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, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /RBSentinelDemo/core/controller/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // RBSentinelDemo 4 | // 5 | // Created by Roshan Nindrai Senthilnathan on 5/24/15. 6 | // Copyright (c) 2015 Roshan Nindrai Senthilnathan. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "RBSentinel.h" 11 | 12 | @interface ViewController () 13 | 14 | @property(nonatomic, strong)RBSentinel *sentinel; 15 | @property (weak, nonatomic) IBOutlet UITextField *userInput; 16 | 17 | @end 18 | 19 | @implementation ViewController 20 | 21 | - (void)viewDidLoad { 22 | [super viewDidLoad]; 23 | self.sentinel = [[RBSentinel alloc] initWithGroupIdentifier:@"group.sentinel"]; 24 | // Do any additional setup after loading the view, typically from a nib. 25 | } 26 | 27 | - (void)didReceiveMemoryWarning { 28 | [super didReceiveMemoryWarning]; 29 | // Dispose of any resources that can be recreated. 30 | } 31 | 32 | - (IBAction)didTapSendData:(id)sender { 33 | 34 | 35 | if(self.userInput.text.length > 0) 36 | [self.sentinel didUpdateResource:@"message" withContent:self.userInput.text]; 37 | 38 | } 39 | 40 | 41 | @end 42 | 43 | -------------------------------------------------------------------------------- /RBSentinelDemo.xcodeproj/xcuserdata/rsenth.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Notification - RBSentinelDemo WatchKit App.xcscheme 8 | 9 | orderHint 10 | 2 11 | 12 | RBSentinelDemo WatchKit App.xcscheme 13 | 14 | orderHint 15 | 1 16 | 17 | RBSentinelDemo.xcscheme 18 | 19 | orderHint 20 | 0 21 | 22 | 23 | SuppressBuildableAutocreation 24 | 25 | FA97C26D1B121BC6008148F9 26 | 27 | primary 28 | 29 | 30 | FA97C2861B121BC6008148F9 31 | 32 | primary 33 | 34 | 35 | FA97C2B11B121C90008148F9 36 | 37 | primary 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /RBSentinelDemo/core/handler/PostHandler.m: -------------------------------------------------------------------------------- 1 | // 2 | // PostHandler.m 3 | // RBOxygenDemo 4 | // 5 | // Created by Roshan Balaji Nindrai SenthilNathan on 5/16/15. 6 | // Copyright (c) 2015 Roshan Balaji Nindrai SenthilNathan. All rights reserved. 7 | // 8 | 9 | #import "PostHandler.h" 10 | 11 | @implementation PostHandler 12 | 13 | -(id)get:(id)parameters { 14 | 15 | NSLog(@"PARAMETERS %@", parameters); 16 | return [NSString stringWithFormat:@"GET Response from parent for parameters %@",parameters]; 17 | 18 | } 19 | 20 | -(id)post:(id)parameters { 21 | 22 | NSLog(@"PARAMETERS %@", parameters); 23 | return [NSString stringWithFormat:@"POST Response from parent for parameters %@",parameters]; 24 | 25 | 26 | } 27 | 28 | -(id)remove:(id)parameters { 29 | 30 | NSLog(@"PARAMETERS %@", parameters); 31 | return [NSString stringWithFormat:@"REMOVE Response from parent for parameters %@",parameters]; 32 | 33 | 34 | } 35 | 36 | -(id)update:(id)parameters { 37 | 38 | NSLog(@"PARAMETERS %@", parameters); 39 | return [NSString stringWithFormat:@"UPDATE Response from parent for parameters %@",parameters]; 40 | 41 | 42 | } 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /RBSentinelDemo WatchKit App/Supporting Files/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | RBSentinelDemo 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | RB.RBSentinelDemo.watchkitapp 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 25 | UISupportedInterfaceOrientations 26 | 27 | UIInterfaceOrientationPortrait 28 | UIInterfaceOrientationPortraitUpsideDown 29 | 30 | WKCompanionAppBundleIdentifier 31 | RB.RBSentinelDemo 32 | WKWatchKitApp 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /RBSentinelDemo WatchKit Extension/Supporting Files/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | RBSentinelDemo WatchKit Extension 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | RB.RBSentinelDemo.watchkitextension 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | NSExtension 26 | 27 | NSExtensionAttributes 28 | 29 | WKAppBundleIdentifier 30 | RB.RBSentinelDemo.watchkitapp 31 | 32 | NSExtensionPointIdentifier 33 | com.apple.watchkit 34 | 35 | RemoteInterfacePrincipalClass 36 | InterfaceController 37 | 38 | 39 | -------------------------------------------------------------------------------- /RBSentinel/RBSentinel.h: -------------------------------------------------------------------------------- 1 | // 2 | // RBSentinel.h 3 | // RBSentinelDemo 4 | // 5 | // Created by Roshan Balaji Nindrai SenthilNathan on 5/16/15. 6 | // Copyright (c) 2015 Roshan Balaji Nindrai SenthilNathan. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @protocol SentinelHandlerProtocol 12 | 13 | @optional 14 | -(id)get:(id)parameters; 15 | 16 | @optional 17 | -(id)post:(id)parameters; 18 | 19 | @optional 20 | -(id)remove:(id)parameters; 21 | 22 | @optional 23 | -(id)update:(id)parameters; 24 | 25 | @end 26 | 27 | @interface RBSentinel : NSObject 28 | 29 | 30 | -(instancetype)initWithGroupIdentifier:(NSString *)groupIdentifier; 31 | 32 | -(void)performRequestofType:(NSString*)requestType 33 | forResource:(NSString *)resource 34 | withParameters:(id)parameters 35 | andCompletionHander:(void (^) (id response))completionHandler; 36 | 37 | 38 | // watchkit methods 39 | 40 | +(void)handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void (^)(NSDictionary *))reply; 41 | 42 | //updates and listeners 43 | 44 | -(void)didUpdateResource:(NSString *)resource withContent:(id)content; 45 | 46 | -(void)addListenerForResource:(NSString *)resource withCompletionHandler:(void (^)(id response))completionHandler; 47 | -(void)removeListenersForResource:(NSString *)resource; 48 | 49 | @end 50 | 51 | -------------------------------------------------------------------------------- /RBSentinelDemo/Supporting Files/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | RB.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /RBSentinelDemo WatchKit App/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "24x24", 5 | "idiom" : "watch", 6 | "scale" : "2x", 7 | "role" : "notificationCenter", 8 | "subtype" : "38mm" 9 | }, 10 | { 11 | "size" : "27.5x27.5", 12 | "idiom" : "watch", 13 | "scale" : "2x", 14 | "role" : "notificationCenter", 15 | "subtype" : "42mm" 16 | }, 17 | { 18 | "size" : "29x29", 19 | "idiom" : "watch", 20 | "role" : "companionSettings", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "size" : "29x29", 25 | "idiom" : "watch", 26 | "role" : "companionSettings", 27 | "scale" : "3x" 28 | }, 29 | { 30 | "size" : "40x40", 31 | "idiom" : "watch", 32 | "scale" : "2x", 33 | "role" : "appLauncher", 34 | "subtype" : "38mm" 35 | }, 36 | { 37 | "size" : "44x44", 38 | "idiom" : "watch", 39 | "scale" : "2x", 40 | "role" : "longLook", 41 | "subtype" : "42mm" 42 | }, 43 | { 44 | "size" : "86x86", 45 | "idiom" : "watch", 46 | "scale" : "2x", 47 | "role" : "quickLook", 48 | "subtype" : "38mm" 49 | }, 50 | { 51 | "size" : "98x98", 52 | "idiom" : "watch", 53 | "scale" : "2x", 54 | "role" : "quickLook", 55 | "subtype" : "42mm" 56 | } 57 | ], 58 | "info" : { 59 | "version" : 1, 60 | "author" : "xcode" 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /RBSentinelDemo WatchKit Extension/NotificationController.m: -------------------------------------------------------------------------------- 1 | // 2 | // NotificationController.m 3 | // RBSentinelDemo WatchKit Extension 4 | // 5 | // Created by Roshan Nindrai Senthilnathan on 5/24/15. 6 | // Copyright (c) 2015 Roshan Nindrai Senthilnathan. All rights reserved. 7 | // 8 | 9 | #import "NotificationController.h" 10 | 11 | 12 | @interface NotificationController() 13 | 14 | @end 15 | 16 | 17 | @implementation NotificationController 18 | 19 | - (instancetype)init { 20 | self = [super init]; 21 | if (self){ 22 | // Initialize variables here. 23 | // Configure interface objects here. 24 | 25 | } 26 | return self; 27 | } 28 | 29 | - (void)willActivate { 30 | // This method is called when watch view controller is about to be visible to user 31 | [super willActivate]; 32 | } 33 | 34 | - (void)didDeactivate { 35 | // This method is called when watch view controller is no longer visible 36 | [super didDeactivate]; 37 | } 38 | 39 | /* 40 | - (void)didReceiveLocalNotification:(UILocalNotification *)localNotification withCompletion:(void (^)(WKUserNotificationInterfaceType))completionHandler { 41 | // This method is called when a local notification needs to be presented. 42 | // Implement it if you use a dynamic notification interface. 43 | // Populate your dynamic notification interface as quickly as possible. 44 | // 45 | // After populating your dynamic notification interface call the completion block. 46 | completionHandler(WKUserNotificationInterfaceTypeCustom); 47 | } 48 | */ 49 | 50 | /* 51 | - (void)didReceiveRemoteNotification:(NSDictionary *)remoteNotification withCompletion:(void (^)(WKUserNotificationInterfaceType))completionHandler { 52 | // This method is called when a remote notification needs to be presented. 53 | // Implement it if you use a dynamic notification interface. 54 | // Populate your dynamic notification interface as quickly as possible. 55 | // 56 | // After populating your dynamic notification interface call the completion block. 57 | completionHandler(WKUserNotificationInterfaceTypeCustom); 58 | } 59 | */ 60 | 61 | @end 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /RBSentinelDemo WatchKit Extension/InterfaceController.m: -------------------------------------------------------------------------------- 1 | // 2 | // InterfaceController.m 3 | // RBSentinelDemo WatchKit Extension 4 | // 5 | // Created by Roshan Nindrai Senthilnathan on 5/24/15. 6 | // Copyright (c) 2015 Roshan Nindrai Senthilnathan. All rights reserved. 7 | // 8 | 9 | #import "InterfaceController.h" 10 | #import "RBSentinel.h" 11 | 12 | 13 | @interface InterfaceController() 14 | 15 | @property(nonatomic, strong)RBSentinel *sentinel; 16 | @property (weak, nonatomic) IBOutlet WKInterfaceLabel *parentAppMessage; 17 | 18 | @end 19 | 20 | 21 | @implementation InterfaceController 22 | 23 | - (void)awakeWithContext:(id)context { 24 | [super awakeWithContext:context]; 25 | self.sentinel = [[RBSentinel alloc] initWithGroupIdentifier:@"group.sentinel"]; 26 | 27 | 28 | __unsafe_unretained typeof(self) weakSelf = self; 29 | 30 | [self.sentinel addListenerForResource:@"message" withCompletionHandler:^(id response) { 31 | 32 | [weakSelf.parentAppMessage setText:response]; 33 | 34 | }]; 35 | // Configure interface objects here. 36 | } 37 | 38 | - (void)willActivate { 39 | // This method is called when watch view controller is about to be visible to user 40 | [super willActivate]; 41 | } 42 | 43 | - (void)didDeactivate { 44 | // This method is called when watch view controller is no longer visible 45 | [super didDeactivate]; 46 | } 47 | - (IBAction)didtapGet { 48 | 49 | [self.sentinel performRequestofType:@"get" forResource:@"post" withParameters:@{@"1":@"2"} andCompletionHander:^(id response) { 50 | NSLog(@"RESPONSE %@", response); 51 | }]; 52 | 53 | } 54 | - (IBAction)didTapPost { 55 | 56 | [self.sentinel performRequestofType:@"post" forResource:@"post" withParameters:@{@"1":@"2"} andCompletionHander:^(id response) { 57 | NSLog(@"RESPONSE %@", response); 58 | }]; 59 | 60 | 61 | } 62 | - (IBAction)didTapRemove { 63 | 64 | [self.sentinel performRequestofType:@"remove" forResource:@"post" withParameters:@{@"1":@"2"} andCompletionHander:^(id response) { 65 | NSLog(@"RESPONSE %@", response); 66 | }]; 67 | 68 | 69 | } 70 | - (IBAction)didTapUpdate { 71 | 72 | [self.sentinel performRequestofType:@"update" forResource:@"post" withParameters:@{@"1":@"2"} andCompletionHander:^(id response) { 73 | NSLog(@"RESPONSE %@", response); 74 | }]; 75 | 76 | 77 | } 78 | 79 | @end 80 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /RBSentinelDemo/core/delegate/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // RBSentinelDemo 4 | // 5 | // Created by Roshan Nindrai Senthilnathan on 5/24/15. 6 | // Copyright (c) 2015 Roshan Nindrai Senthilnathan. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | #import "RBSentinel.h" 11 | 12 | @interface AppDelegate () 13 | 14 | @end 15 | 16 | @implementation AppDelegate 17 | 18 | 19 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 20 | // Override point for customization after application launch. 21 | return YES; 22 | } 23 | 24 | - (void)applicationWillResignActive:(UIApplication *)application { 25 | // 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. 26 | // 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. 27 | } 28 | 29 | - (void)applicationDidEnterBackground:(UIApplication *)application { 30 | // 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. 31 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 32 | } 33 | 34 | - (void)applicationWillEnterForeground:(UIApplication *)application { 35 | // 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. 36 | } 37 | 38 | - (void)applicationDidBecomeActive:(UIApplication *)application { 39 | // 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. 40 | } 41 | 42 | - (void)applicationWillTerminate:(UIApplication *)application { 43 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 44 | } 45 | 46 | -(void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void (^)(NSDictionary *))reply { 47 | 48 | 49 | [RBSentinel handleWatchKitExtensionRequest:userInfo reply:reply]; 50 | 51 | } 52 | 53 | @end 54 | -------------------------------------------------------------------------------- /RBSentinelDemo/core/system/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 20 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RBSentinel 2 | 3 | RBSentinel helps in improving the communication between the applewatch and the parent application. It opens up a REST based interface to handle information needed by the watchapp. 4 | 5 |

6 | 7 |

8 |

9 | 10 |

11 | 12 | #Installation 13 | 14 | RBSentinel can be added to your project manually by adding the RBSentinel.h and .m to the project folder. The prefered installation method is through cocoapods 15 | 16 | ``` 17 | pod 'RBSentinel' 18 | 19 | ``` 20 | 21 | # Usage 22 | 23 | RBSentinel was inspired by MMWormhole, with a way to perfom CRUD operations over a specific resource. Sentinel has the ability to listen to updates on specific resource even when the app is not open or in background. 24 | 25 | Initialization 26 | 27 | ``` 28 | self.sentinel = [[Sentinel alloc] initWithGroupIdentifier:@"group.sentinel"]; 29 | ``` 30 | 31 | with groupIdentifier being the app groups identifier 32 | 33 | To add a listener to a specific resource 34 | ``` 35 | [self.sentinel addListenerForResource:@"message" withCompletionHandler:^(id response) { 36 | [weakSelf.parentAppMessage setText:response]; 37 | }]; 38 | ``` 39 | The completion handler will get called when ever there is an update posted on that specific resource. Multiple listeners can be added to a same resouce. These listener basically listens for updates on a specific resource. To post an update to a specific resouce 40 | 41 | ``` 42 | [self.sentinel didUpdateResource:@"message" withContent:self.userInput.text]; 43 | ``` 44 | The above update triggers the listener that was added previously to that specific topic. 45 | 46 | # Handlers 47 | 48 | Apart from listeners, Sentinel enables us to perfrom get, post, update, remove and custom operations over a specific resource type. 49 | To enable handlers the appdelegate needs to have the following line 50 | ``` 51 | [Sentinel handleWatchKitExtensionRequest:userInfo reply:reply]; 52 | ``` 53 | 54 | For example if the resource type is post, then sentinel looks for a PostHandler class, and fires either get, post, update, remove methods. A typical request looks like 55 | 56 | ``` 57 | [self.sentinel performRequestofType:GET forResource:@"post" withParameters:@{@"1":@"2"} andCompletionHander:^(id response) { 58 | NSLog(@"RESPONSE %@", response); 59 | }]; 60 | 61 | ``` 62 | 63 | The above request invokes the post method with PostHander class. The following is the way how Sentinel resolves resource to handlers. 64 | 65 | Post => PostHandler 66 | message => MessageHandler 67 | 68 | ``` 69 | @interface PostHandler : NSObject 70 | 71 | @end 72 | 73 | @implementation PostHandler 74 | 75 | -(id)get:(id)parameters { 76 | 77 | // gets called for request type get 78 | 79 | } 80 | 81 | -(id)post:(id)parameters { 82 | 83 | // gets called for request type post 84 | 85 | } 86 | 87 | -(id)remove:(id)parameters { 88 | 89 | // gets called for request type remove 90 | 91 | } 92 | 93 | -(id)update:(id)parameters { 94 | 95 | // gets called for request type update 96 | 97 | } 98 | ``` 99 | # Lincense 100 | 101 | The MIT License (MIT) 102 | 103 | Copyright (c) 2014 RoshanNindrai 104 | 105 | Permission is hereby granted, free of charge, to any person obtaining a copy 106 | of this software and associated documentation files (the "Software"), to deal 107 | in the Software without restriction, including without limitation the rights 108 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 109 | copies of the Software, and to permit persons to whom the Software is 110 | furnished to do so, subject to the following conditions: 111 | 112 | The above copyright notice and this permission notice shall be included in all 113 | copies or substantial portions of the Software. 114 | 115 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 116 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 117 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 118 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 119 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 120 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 121 | SOFTWARE. 122 | 123 | 124 | 125 | 126 | -------------------------------------------------------------------------------- /RBSentinelDemo WatchKit App/Base.lproj/Interface.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 20 | 22 | 23 | 28 | 33 | 38 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /RBSentinelDemo.xcodeproj/xcuserdata/rsenth.xcuserdatad/xcschemes/RBSentinelDemo.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 47 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 65 | 66 | 75 | 77 | 83 | 84 | 85 | 86 | 87 | 88 | 94 | 96 | 102 | 103 | 104 | 105 | 107 | 108 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /RBSentinelDemo/core/system/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /RBSentinelDemo.xcodeproj/xcuserdata/rsenth.xcuserdatad/xcschemes/RBSentinelDemo WatchKit App.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 43 | 49 | 50 | 51 | 52 | 53 | 58 | 59 | 60 | 61 | 67 | 68 | 69 | 70 | 79 | 83 | 89 | 90 | 91 | 92 | 98 | 99 | 100 | 101 | 102 | 103 | 109 | 113 | 119 | 120 | 121 | 122 | 128 | 129 | 130 | 131 | 133 | 134 | 137 | 138 | 139 | -------------------------------------------------------------------------------- /RBSentinelDemo.xcodeproj/xcuserdata/rsenth.xcuserdatad/xcschemes/Notification - RBSentinelDemo WatchKit App.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 43 | 49 | 50 | 51 | 52 | 53 | 58 | 59 | 60 | 61 | 67 | 68 | 69 | 70 | 81 | 85 | 91 | 92 | 93 | 94 | 100 | 101 | 102 | 103 | 104 | 105 | 113 | 117 | 123 | 124 | 125 | 126 | 132 | 133 | 134 | 135 | 137 | 138 | 141 | 142 | 143 | -------------------------------------------------------------------------------- /RBSentinel/RBSentinel.m: -------------------------------------------------------------------------------- 1 | // 2 | // RBSentinel.m 3 | // RBSentinelDemo 4 | // 5 | // Created by Roshan Balaji Nindrai SenthilNathan on 5/16/15. 6 | // Copyright (c) 2015 Roshan Balaji Nindrai SenthilNathan. All rights reserved. 7 | // 8 | #import "RBSentinel.h" 9 | #include 10 | #import 11 | 12 | @interface NSString (Sentinel) 13 | 14 | -(NSString *)capitalizedFirstLetter; 15 | 16 | @end 17 | 18 | @implementation NSString (Sentinel) 19 | 20 | -(NSString *) capitalizedFirstLetter { 21 | NSString *capString = self; 22 | if (self.length <= 1) { 23 | capString = self.capitalizedString; 24 | } else { 25 | capString = [NSString stringWithFormat:@"%@%@", 26 | [[self substringToIndex:1] uppercaseString], 27 | [self substringFromIndex:1]]; 28 | } 29 | return capString; 30 | } 31 | 32 | -(NSString *)selectorMethod { 33 | 34 | return [self stringByAppendingString:@":"]; 35 | 36 | } 37 | 38 | @end 39 | 40 | 41 | NSString *const KHANDLERCLASSSUFFIX = @"Handler"; 42 | NSString *const KSENTINELREQUESTTYPE = @"type"; 43 | NSString *const KSENTINELREQUESTRESOURCE = @"resource"; 44 | NSString *const KSENTINELREQUESTPARAMETER = @"parameters"; 45 | NSString *const KSENTINELRESPONSE = @"parameters"; 46 | NSString *const KSENTINELIDENTIFIER = @"sentinel"; 47 | NSString *const KSENTINELERRORDOMAIN = @"SENTINEL_ERROR"; 48 | 49 | @interface RBSentinel () 50 | 51 | @property(nonatomic, strong) NSMutableDictionary *routeHandlers; 52 | @property(nonatomic, strong) NSString *resourcePath; 53 | @property(nonatomic, strong) NSURL *fileURL; 54 | @property(nonatomic, strong) NSFileManager *fileManager; 55 | @property(nonatomic, strong) NSString *groupIdentifier; 56 | @property(nonatomic, strong) id response; 57 | @property(nonatomic, strong) NSMutableDictionary *listenersCallbacks; 58 | @property(nonatomic, strong) BOOL(^handler)(NSDictionary *parameters); 59 | 60 | @end 61 | 62 | @implementation RBSentinel 63 | 64 | #pragma clang diagnostic ignored "-Warc-performSelector-leaks" 65 | 66 | -(instancetype)init { 67 | 68 | self = [super init]; 69 | 70 | if(self) { 71 | 72 | self.routeHandlers = [NSMutableDictionary new]; 73 | self.listenersCallbacks = [NSMutableDictionary new]; 74 | self.fileManager = [NSFileManager new]; 75 | 76 | [[NSNotificationCenter defaultCenter] addObserver:self 77 | selector:@selector(DidReceiveSentinelNotification:) 78 | name:KSENTINELIDENTIFIER object:nil]; 79 | 80 | } 81 | 82 | return self; 83 | 84 | } 85 | 86 | -(instancetype)initWithGroupIdentifier:(NSString *)groupIdentifier { 87 | 88 | self = [[self class] new]; 89 | 90 | if(self) { 91 | self.groupIdentifier = groupIdentifier; 92 | } 93 | return self; 94 | } 95 | 96 | 97 | + (instancetype)dock { 98 | static RBSentinel *sharedDock = nil; 99 | static dispatch_once_t onceToken; 100 | dispatch_once(&onceToken, ^{ 101 | sharedDock = [[self alloc] init]; 102 | }); 103 | return sharedDock; 104 | } 105 | 106 | +(void)handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void (^)(NSDictionary *))reply { 107 | 108 | [[self dock] fullfillRequestofType:[userInfo objectForKey:KSENTINELREQUESTTYPE] 109 | forResource:[userInfo objectForKey:KSENTINELREQUESTRESOURCE] 110 | withParameters:[userInfo objectForKey:KSENTINELREQUESTPARAMETER] 111 | andCompletionHander:reply]; 112 | 113 | 114 | } 115 | 116 | 117 | #pragma mark accesors / mutators 118 | 119 | -(void)setGroupIdentifier:(NSString *)groupIdentifier { 120 | 121 | 122 | if(_groupIdentifier != groupIdentifier) { 123 | 124 | _groupIdentifier = groupIdentifier; 125 | self.fileURL = [self.fileManager 126 | containerURLForSecurityApplicationGroupIdentifier: 127 | _groupIdentifier]; 128 | 129 | } 130 | 131 | 132 | } 133 | 134 | -(void)setFileURL:(NSURL *)fileURL { 135 | 136 | if(_fileURL != fileURL) { 137 | 138 | _fileURL = fileURL; 139 | self.resourcePath = [_fileURL absoluteString]; 140 | [self.fileManager createDirectoryAtPath:_resourcePath 141 | withIntermediateDirectories:YES attributes:nil error:NULL]; 142 | 143 | } 144 | } 145 | 146 | -(void)fileForResource:(NSURL *)fileURL { 147 | 148 | if(_fileURL != fileURL) { 149 | 150 | _fileURL = [fileURL URLByAppendingPathComponent:KSENTINELIDENTIFIER]; 151 | 152 | } 153 | } 154 | 155 | #pragma mark listeners 156 | 157 | -(void)addListenerForResource:(NSString *)resource 158 | withCompletionHandler:(void (^)(id response))completionHandler { 159 | 160 | NSMutableArray *listeners = [self.listenersCallbacks objectForKey:resource]; 161 | 162 | if(listeners == nil) 163 | listeners = [NSMutableArray new]; 164 | 165 | [listeners addObject:completionHandler]; 166 | [self.listenersCallbacks setObject:listeners forKey:resource]; 167 | 168 | [self subscribeToNotificationForIdentifier:resource]; 169 | 170 | } 171 | 172 | 173 | -(void)removeListenersForResource:(NSString *)resource { 174 | 175 | NSMutableArray *listeners = [self.listenersCallbacks objectForKey:resource]; 176 | 177 | if(listeners != nil) 178 | [self.listenersCallbacks setObject:[NSMutableArray new] forKey:resource]; 179 | 180 | 181 | } 182 | 183 | -(void)subscribeToNotificationForIdentifier:(NSString *)resource { 184 | 185 | CFNotificationCenterRef const notificationCenter = CFNotificationCenterGetDarwinNotifyCenter(); 186 | CFStringRef resourceString = (__bridge CFStringRef)(resource); 187 | CFNotificationCenterAddObserver(notificationCenter, 188 | (__bridge const void *)(self), 189 | darwinNotificationCallback, 190 | resourceString, 191 | NULL, 192 | CFNotificationSuspensionBehaviorDeliverImmediately); 193 | 194 | } 195 | 196 | #pragma mark Private methods 197 | 198 | -(void)didUpdateResource:(NSString *)resource withContent:(id)content { 199 | 200 | if(resource == nil || content == nil) 201 | return; 202 | 203 | NSString *resourcePath = [self.resourcePath stringByAppendingString:resource]; 204 | 205 | if(resourcePath == nil) 206 | return; 207 | 208 | NSData *_contentData = [NSKeyedArchiver archivedDataWithRootObject:content]; 209 | 210 | if([_contentData isEqual:nil]) 211 | return; 212 | 213 | NSError *error; 214 | 215 | BOOL _didWrite = [_contentData writeToURL:[NSURL URLWithString:resourcePath] 216 | options:NSDataWritingAtomic error:&error]; 217 | if (error) { 218 | NSLog(@"Fail: %@", [error localizedDescription]); 219 | } 220 | 221 | if (_didWrite) { 222 | // send out notification 223 | [self sendUpdateNotificationForResouce:resource]; 224 | } 225 | 226 | } 227 | 228 | -(void)performRequestofType:(NSString*)requestType 229 | forResource:(NSString *)resource 230 | withParameters:(id)parameters andCompletionHander:(void (^) (id response))completionHandler { 231 | 232 | resource = [resource capitalizedFirstLetter]; 233 | NSString *callType = [requestType selectorMethod]; 234 | [WKInterfaceController openParentApplication:@{KSENTINELREQUESTTYPE:callType, 235 | KSENTINELREQUESTRESOURCE:resource, 236 | KSENTINELREQUESTPARAMETER:parameters} 237 | 238 | 239 | reply:^(NSDictionary *replyInfo, NSError *error) { 240 | if(completionHandler) 241 | completionHandler([replyInfo objectForKey:KSENTINELRESPONSE]); 242 | }]; 243 | 244 | } 245 | 246 | -(void)fullfillRequestofType:(NSString *)requestType 247 | forResource:(NSString *)resource 248 | withParameters:(id)parameters andCompletionHander:(void (^) (id response))completionHandler { 249 | 250 | 251 | id handler = [self getHandlerForResource:resource]; 252 | 253 | id response = nil; 254 | 255 | if(handler != nil) { 256 | 257 | if([handler respondsToSelector:NSSelectorFromString(requestType)]){ 258 | 259 | response = [self invokeMethod:requestType onHandler:handler withParameters:parameters]; 260 | 261 | } 262 | 263 | } 264 | 265 | if(completionHandler) 266 | completionHandler(@{KSENTINELRESPONSE: response}); 267 | 268 | 269 | } 270 | 271 | #pragma mark notification 272 | 273 | -(void)DidReceiveSentinelNotification:(NSNotification *)notification { 274 | 275 | NSDictionary *userInfo = notification.userInfo; 276 | 277 | if(userInfo == nil || [userInfo objectForKey:KSENTINELREQUESTRESOURCE] == nil) 278 | return; 279 | 280 | NSString *resourceString = [userInfo objectForKey:KSENTINELREQUESTRESOURCE]; 281 | 282 | [self fireListenersForResource:resourceString]; 283 | 284 | } 285 | 286 | -(void)fireListenersForResource:(NSString *)resourceString { 287 | 288 | NSMutableArray *_listenerBlocks = [_listenersCallbacks objectForKey:resourceString]; 289 | 290 | for(void(^listener)(id response) in _listenerBlocks) { 291 | 292 | id response = [self responseForResource:resourceString]; 293 | 294 | if(listener) 295 | listener(response); 296 | 297 | } 298 | 299 | } 300 | 301 | -(id)responseForResource:(NSString *)resource { 302 | 303 | NSData *savedData = [NSData dataWithContentsOfURL:[NSURL URLWithString:[self.resourcePath stringByAppendingString:resource]]]; 304 | 305 | if(savedData != nil) 306 | return [NSKeyedUnarchiver unarchiveObjectWithData:savedData]; 307 | 308 | return nil; 309 | } 310 | 311 | void darwinNotificationCallback(CFNotificationCenterRef center, 312 | void * observer, 313 | CFStringRef name, 314 | void const * object, 315 | CFDictionaryRef userInfo) { 316 | 317 | NSString *resourceString = (__bridge NSString *)(name); 318 | 319 | [[NSNotificationCenter defaultCenter] postNotificationName:KSENTINELIDENTIFIER 320 | object:nil userInfo:@{KSENTINELREQUESTRESOURCE:resourceString}]; 321 | 322 | } 323 | 324 | -(void)sendUpdateNotificationForResouce:(NSString *)resource { 325 | 326 | if([resource isEqual:nil]) 327 | return; 328 | 329 | CFNotificationCenterRef const notificationCenter = CFNotificationCenterGetDarwinNotifyCenter(); 330 | CFStringRef resourceString = (__bridge CFStringRef)(resource); 331 | CFNotificationCenterPostNotification(notificationCenter, resourceString, NULL, NULL, YES); 332 | 333 | 334 | } 335 | 336 | # pragma mark helper methods 337 | 338 | -(id)getHandlerForResource:(NSString *)resource { 339 | 340 | 341 | if([self.routeHandlers objectForKey:resource] == nil) { 342 | 343 | NSString *HandlerClassName = [resource stringByAppendingString:KHANDLERCLASSSUFFIX]; 344 | Class handlerClass = NSClassFromString(HandlerClassName); 345 | if(handlerClass != nil) 346 | [self.routeHandlers setObject:[handlerClass new] forKey:resource]; 347 | 348 | } 349 | 350 | return [self.routeHandlers objectForKey:resource]; 351 | 352 | } 353 | 354 | -(id)invokeMethod:(NSString *)methodName onHandler:(id)handler withParameters:(id)parameters { 355 | 356 | NSInvocation *invocation = [NSInvocation invocationWithMethodSignature: 357 | [[handler class] instanceMethodSignatureForSelector:NSSelectorFromString(methodName)]]; 358 | [invocation setSelector:NSSelectorFromString(methodName)]; 359 | [invocation setTarget:handler]; 360 | [invocation setArgument:¶meters atIndex:2]; 361 | [invocation invoke]; 362 | [invocation getReturnValue:&_response]; 363 | 364 | return _response; 365 | 366 | } 367 | 368 | #pragma marok error messages 369 | 370 | -(NSDictionary *)noHandlerMethodErroruserInfo { 371 | 372 | return @{ 373 | NSLocalizedDescriptionKey: NSLocalizedString(@"call handler method was unsuccessful.", nil), 374 | NSLocalizedFailureReasonErrorKey: NSLocalizedString(@"Handler method was not found ", nil), 375 | NSLocalizedRecoverySuggestionErrorKey: NSLocalizedString(@"Please check your handler method name", nil) 376 | }; 377 | 378 | } 379 | 380 | -(NSDictionary *)noHandlerErroruserInfo { 381 | 382 | return @{ 383 | NSLocalizedDescriptionKey: NSLocalizedString(@"call handler method was unsuccessful.", nil), 384 | NSLocalizedFailureReasonErrorKey: NSLocalizedString(@"Handler method was not found ", nil), 385 | NSLocalizedRecoverySuggestionErrorKey: NSLocalizedString(@"Please check your handler method name", nil) 386 | }; 387 | 388 | } 389 | 390 | @end 391 | -------------------------------------------------------------------------------- /RBSentinelDemo.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | FA97C2741B121BC6008148F9 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = FA97C2731B121BC6008148F9 /* main.m */; }; 11 | FA97C2771B121BC6008148F9 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = FA97C2761B121BC6008148F9 /* AppDelegate.m */; }; 12 | FA97C27A1B121BC6008148F9 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FA97C2791B121BC6008148F9 /* ViewController.m */; }; 13 | FA97C27D1B121BC6008148F9 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FA97C27B1B121BC6008148F9 /* Main.storyboard */; }; 14 | FA97C27F1B121BC6008148F9 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = FA97C27E1B121BC6008148F9 /* Images.xcassets */; }; 15 | FA97C2821B121BC6008148F9 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = FA97C2801B121BC6008148F9 /* LaunchScreen.xib */; }; 16 | FA97C28E1B121BC6008148F9 /* RBSentinelDemoTests.m in Sources */ = {isa = PBXBuildFile; fileRef = FA97C28D1B121BC6008148F9 /* RBSentinelDemoTests.m */; }; 17 | FA97C29E1B121C2C008148F9 /* RBSentinel.m in Sources */ = {isa = PBXBuildFile; fileRef = FA97C29D1B121C2C008148F9 /* RBSentinel.m */; }; 18 | FA97C2AA1B121C90008148F9 /* InterfaceController.m in Sources */ = {isa = PBXBuildFile; fileRef = FA97C2A91B121C90008148F9 /* InterfaceController.m */; }; 19 | FA97C2AD1B121C90008148F9 /* NotificationController.m in Sources */ = {isa = PBXBuildFile; fileRef = FA97C2AC1B121C90008148F9 /* NotificationController.m */; }; 20 | FA97C2AF1B121C90008148F9 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = FA97C2AE1B121C90008148F9 /* Images.xcassets */; }; 21 | FA97C2B31B121C90008148F9 /* RBSentinelDemo WatchKit App.app in Resources */ = {isa = PBXBuildFile; fileRef = FA97C2B21B121C90008148F9 /* RBSentinelDemo WatchKit App.app */; }; 22 | FA97C2BB1B121C90008148F9 /* Interface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FA97C2B91B121C90008148F9 /* Interface.storyboard */; }; 23 | FA97C2BD1B121C90008148F9 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = FA97C2BC1B121C90008148F9 /* Images.xcassets */; }; 24 | FA97C2C01B121C90008148F9 /* RBSentinelDemo WatchKit Extension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = FA97C2A31B121C90008148F9 /* RBSentinelDemo WatchKit Extension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 25 | FA97C2CB1B121D86008148F9 /* PostHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = FA97C2CA1B121D86008148F9 /* PostHandler.m */; }; 26 | FA97C2CC1B121DAD008148F9 /* RBSentinel.m in Sources */ = {isa = PBXBuildFile; fileRef = FA97C29D1B121C2C008148F9 /* RBSentinel.m */; }; 27 | /* End PBXBuildFile section */ 28 | 29 | /* Begin PBXContainerItemProxy section */ 30 | FA97C2881B121BC6008148F9 /* PBXContainerItemProxy */ = { 31 | isa = PBXContainerItemProxy; 32 | containerPortal = FA97C2661B121BC5008148F9 /* Project object */; 33 | proxyType = 1; 34 | remoteGlobalIDString = FA97C26D1B121BC6008148F9; 35 | remoteInfo = RBSentinelDemo; 36 | }; 37 | FA97C2B41B121C90008148F9 /* PBXContainerItemProxy */ = { 38 | isa = PBXContainerItemProxy; 39 | containerPortal = FA97C2661B121BC5008148F9 /* Project object */; 40 | proxyType = 1; 41 | remoteGlobalIDString = FA97C2B11B121C90008148F9; 42 | remoteInfo = "RBSentinelDemo WatchKit App"; 43 | }; 44 | FA97C2BE1B121C90008148F9 /* PBXContainerItemProxy */ = { 45 | isa = PBXContainerItemProxy; 46 | containerPortal = FA97C2661B121BC5008148F9 /* Project object */; 47 | proxyType = 1; 48 | remoteGlobalIDString = FA97C2A21B121C90008148F9; 49 | remoteInfo = "RBSentinelDemo WatchKit Extension"; 50 | }; 51 | /* End PBXContainerItemProxy section */ 52 | 53 | /* Begin PBXCopyFilesBuildPhase section */ 54 | FA97C2C71B121C90008148F9 /* Embed App Extensions */ = { 55 | isa = PBXCopyFilesBuildPhase; 56 | buildActionMask = 2147483647; 57 | dstPath = ""; 58 | dstSubfolderSpec = 13; 59 | files = ( 60 | FA97C2C01B121C90008148F9 /* RBSentinelDemo WatchKit Extension.appex in Embed App Extensions */, 61 | ); 62 | name = "Embed App Extensions"; 63 | runOnlyForDeploymentPostprocessing = 0; 64 | }; 65 | /* End PBXCopyFilesBuildPhase section */ 66 | 67 | /* Begin PBXFileReference section */ 68 | FA97C26E1B121BC6008148F9 /* RBSentinelDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RBSentinelDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 69 | FA97C2721B121BC6008148F9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 70 | FA97C2731B121BC6008148F9 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 71 | FA97C2751B121BC6008148F9 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 72 | FA97C2761B121BC6008148F9 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 73 | FA97C2781B121BC6008148F9 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 74 | FA97C2791B121BC6008148F9 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 75 | FA97C27C1B121BC6008148F9 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 76 | FA97C27E1B121BC6008148F9 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 77 | FA97C2811B121BC6008148F9 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 78 | FA97C2871B121BC6008148F9 /* RBSentinelDemoTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RBSentinelDemoTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 79 | FA97C28C1B121BC6008148F9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 80 | FA97C28D1B121BC6008148F9 /* RBSentinelDemoTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RBSentinelDemoTests.m; sourceTree = ""; }; 81 | FA97C29C1B121C2C008148F9 /* RBSentinel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RBSentinel.h; sourceTree = ""; }; 82 | FA97C29D1B121C2C008148F9 /* RBSentinel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RBSentinel.m; sourceTree = ""; }; 83 | FA97C2A31B121C90008148F9 /* RBSentinelDemo WatchKit Extension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "RBSentinelDemo WatchKit Extension.appex"; sourceTree = BUILT_PRODUCTS_DIR; }; 84 | FA97C2A61B121C90008148F9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 85 | FA97C2A71B121C90008148F9 /* PushNotificationPayload.apns */ = {isa = PBXFileReference; lastKnownFileType = text; path = PushNotificationPayload.apns; sourceTree = ""; }; 86 | FA97C2A81B121C90008148F9 /* InterfaceController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = InterfaceController.h; sourceTree = ""; }; 87 | FA97C2A91B121C90008148F9 /* InterfaceController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = InterfaceController.m; sourceTree = ""; }; 88 | FA97C2AB1B121C90008148F9 /* NotificationController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NotificationController.h; sourceTree = ""; }; 89 | FA97C2AC1B121C90008148F9 /* NotificationController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NotificationController.m; sourceTree = ""; }; 90 | FA97C2AE1B121C90008148F9 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 91 | FA97C2B21B121C90008148F9 /* RBSentinelDemo WatchKit App.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "RBSentinelDemo WatchKit App.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 92 | FA97C2B81B121C90008148F9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 93 | FA97C2BA1B121C90008148F9 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Interface.storyboard; sourceTree = ""; }; 94 | FA97C2BC1B121C90008148F9 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 95 | FA97C2C91B121D86008148F9 /* PostHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PostHandler.h; sourceTree = ""; }; 96 | FA97C2CA1B121D86008148F9 /* PostHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PostHandler.m; sourceTree = ""; }; 97 | FA97C2CD1B121EEC008148F9 /* RBSentinelDemo WatchKit Extension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "RBSentinelDemo WatchKit Extension.entitlements"; sourceTree = ""; }; 98 | FA97C2CE1B121F03008148F9 /* RBSentinelDemo.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = RBSentinelDemo.entitlements; sourceTree = ""; }; 99 | /* End PBXFileReference section */ 100 | 101 | /* Begin PBXFrameworksBuildPhase section */ 102 | FA97C26B1B121BC6008148F9 /* Frameworks */ = { 103 | isa = PBXFrameworksBuildPhase; 104 | buildActionMask = 2147483647; 105 | files = ( 106 | ); 107 | runOnlyForDeploymentPostprocessing = 0; 108 | }; 109 | FA97C2841B121BC6008148F9 /* Frameworks */ = { 110 | isa = PBXFrameworksBuildPhase; 111 | buildActionMask = 2147483647; 112 | files = ( 113 | ); 114 | runOnlyForDeploymentPostprocessing = 0; 115 | }; 116 | FA97C2A01B121C90008148F9 /* Frameworks */ = { 117 | isa = PBXFrameworksBuildPhase; 118 | buildActionMask = 2147483647; 119 | files = ( 120 | ); 121 | runOnlyForDeploymentPostprocessing = 0; 122 | }; 123 | /* End PBXFrameworksBuildPhase section */ 124 | 125 | /* Begin PBXGroup section */ 126 | FA97C2651B121BC5008148F9 = { 127 | isa = PBXGroup; 128 | children = ( 129 | FA97C29B1B121C0E008148F9 /* RBSentinel */, 130 | FA97C2701B121BC6008148F9 /* RBSentinelDemo */, 131 | FA97C28A1B121BC6008148F9 /* RBSentinelDemoTests */, 132 | FA97C2A41B121C90008148F9 /* RBSentinelDemo WatchKit Extension */, 133 | FA97C2B61B121C90008148F9 /* RBSentinelDemo WatchKit App */, 134 | FA97C26F1B121BC6008148F9 /* Products */, 135 | ); 136 | sourceTree = ""; 137 | }; 138 | FA97C26F1B121BC6008148F9 /* Products */ = { 139 | isa = PBXGroup; 140 | children = ( 141 | FA97C26E1B121BC6008148F9 /* RBSentinelDemo.app */, 142 | FA97C2871B121BC6008148F9 /* RBSentinelDemoTests.xctest */, 143 | FA97C2A31B121C90008148F9 /* RBSentinelDemo WatchKit Extension.appex */, 144 | FA97C2B21B121C90008148F9 /* RBSentinelDemo WatchKit App.app */, 145 | ); 146 | name = Products; 147 | sourceTree = ""; 148 | }; 149 | FA97C2701B121BC6008148F9 /* RBSentinelDemo */ = { 150 | isa = PBXGroup; 151 | children = ( 152 | FA97C2CE1B121F03008148F9 /* RBSentinelDemo.entitlements */, 153 | FA97C2971B121BD5008148F9 /* core */, 154 | FA97C2711B121BC6008148F9 /* Supporting Files */, 155 | ); 156 | path = RBSentinelDemo; 157 | sourceTree = ""; 158 | }; 159 | FA97C2711B121BC6008148F9 /* Supporting Files */ = { 160 | isa = PBXGroup; 161 | children = ( 162 | FA97C2721B121BC6008148F9 /* Info.plist */, 163 | FA97C2731B121BC6008148F9 /* main.m */, 164 | ); 165 | path = "Supporting Files"; 166 | sourceTree = ""; 167 | }; 168 | FA97C28A1B121BC6008148F9 /* RBSentinelDemoTests */ = { 169 | isa = PBXGroup; 170 | children = ( 171 | FA97C28D1B121BC6008148F9 /* RBSentinelDemoTests.m */, 172 | FA97C28B1B121BC6008148F9 /* Supporting Files */, 173 | ); 174 | path = RBSentinelDemoTests; 175 | sourceTree = ""; 176 | }; 177 | FA97C28B1B121BC6008148F9 /* Supporting Files */ = { 178 | isa = PBXGroup; 179 | children = ( 180 | FA97C28C1B121BC6008148F9 /* Info.plist */, 181 | ); 182 | path = "Supporting Files"; 183 | sourceTree = ""; 184 | }; 185 | FA97C2971B121BD5008148F9 /* core */ = { 186 | isa = PBXGroup; 187 | children = ( 188 | FA97C2C81B121D74008148F9 /* handler */, 189 | FA97C29A1B121BF2008148F9 /* system */, 190 | FA97C2991B121BE7008148F9 /* delegate */, 191 | FA97C2981B121BDB008148F9 /* controller */, 192 | ); 193 | path = core; 194 | sourceTree = ""; 195 | }; 196 | FA97C2981B121BDB008148F9 /* controller */ = { 197 | isa = PBXGroup; 198 | children = ( 199 | FA97C2781B121BC6008148F9 /* ViewController.h */, 200 | FA97C2791B121BC6008148F9 /* ViewController.m */, 201 | ); 202 | path = controller; 203 | sourceTree = ""; 204 | }; 205 | FA97C2991B121BE7008148F9 /* delegate */ = { 206 | isa = PBXGroup; 207 | children = ( 208 | FA97C2751B121BC6008148F9 /* AppDelegate.h */, 209 | FA97C2761B121BC6008148F9 /* AppDelegate.m */, 210 | ); 211 | path = delegate; 212 | sourceTree = ""; 213 | }; 214 | FA97C29A1B121BF2008148F9 /* system */ = { 215 | isa = PBXGroup; 216 | children = ( 217 | FA97C27B1B121BC6008148F9 /* Main.storyboard */, 218 | FA97C27E1B121BC6008148F9 /* Images.xcassets */, 219 | FA97C2801B121BC6008148F9 /* LaunchScreen.xib */, 220 | ); 221 | path = system; 222 | sourceTree = ""; 223 | }; 224 | FA97C29B1B121C0E008148F9 /* RBSentinel */ = { 225 | isa = PBXGroup; 226 | children = ( 227 | FA97C29C1B121C2C008148F9 /* RBSentinel.h */, 228 | FA97C29D1B121C2C008148F9 /* RBSentinel.m */, 229 | ); 230 | path = RBSentinel; 231 | sourceTree = ""; 232 | }; 233 | FA97C2A41B121C90008148F9 /* RBSentinelDemo WatchKit Extension */ = { 234 | isa = PBXGroup; 235 | children = ( 236 | FA97C2CD1B121EEC008148F9 /* RBSentinelDemo WatchKit Extension.entitlements */, 237 | FA97C2A81B121C90008148F9 /* InterfaceController.h */, 238 | FA97C2A91B121C90008148F9 /* InterfaceController.m */, 239 | FA97C2AB1B121C90008148F9 /* NotificationController.h */, 240 | FA97C2AC1B121C90008148F9 /* NotificationController.m */, 241 | FA97C2AE1B121C90008148F9 /* Images.xcassets */, 242 | FA97C2A51B121C90008148F9 /* Supporting Files */, 243 | ); 244 | path = "RBSentinelDemo WatchKit Extension"; 245 | sourceTree = ""; 246 | }; 247 | FA97C2A51B121C90008148F9 /* Supporting Files */ = { 248 | isa = PBXGroup; 249 | children = ( 250 | FA97C2A61B121C90008148F9 /* Info.plist */, 251 | FA97C2A71B121C90008148F9 /* PushNotificationPayload.apns */, 252 | ); 253 | path = "Supporting Files"; 254 | sourceTree = ""; 255 | }; 256 | FA97C2B61B121C90008148F9 /* RBSentinelDemo WatchKit App */ = { 257 | isa = PBXGroup; 258 | children = ( 259 | FA97C2B91B121C90008148F9 /* Interface.storyboard */, 260 | FA97C2BC1B121C90008148F9 /* Images.xcassets */, 261 | FA97C2B71B121C90008148F9 /* Supporting Files */, 262 | ); 263 | path = "RBSentinelDemo WatchKit App"; 264 | sourceTree = ""; 265 | }; 266 | FA97C2B71B121C90008148F9 /* Supporting Files */ = { 267 | isa = PBXGroup; 268 | children = ( 269 | FA97C2B81B121C90008148F9 /* Info.plist */, 270 | ); 271 | path = "Supporting Files"; 272 | sourceTree = ""; 273 | }; 274 | FA97C2C81B121D74008148F9 /* handler */ = { 275 | isa = PBXGroup; 276 | children = ( 277 | FA97C2C91B121D86008148F9 /* PostHandler.h */, 278 | FA97C2CA1B121D86008148F9 /* PostHandler.m */, 279 | ); 280 | path = handler; 281 | sourceTree = ""; 282 | }; 283 | /* End PBXGroup section */ 284 | 285 | /* Begin PBXNativeTarget section */ 286 | FA97C26D1B121BC6008148F9 /* RBSentinelDemo */ = { 287 | isa = PBXNativeTarget; 288 | buildConfigurationList = FA97C2911B121BC6008148F9 /* Build configuration list for PBXNativeTarget "RBSentinelDemo" */; 289 | buildPhases = ( 290 | FA97C26A1B121BC6008148F9 /* Sources */, 291 | FA97C26B1B121BC6008148F9 /* Frameworks */, 292 | FA97C26C1B121BC6008148F9 /* Resources */, 293 | FA97C2C71B121C90008148F9 /* Embed App Extensions */, 294 | ); 295 | buildRules = ( 296 | ); 297 | dependencies = ( 298 | FA97C2BF1B121C90008148F9 /* PBXTargetDependency */, 299 | ); 300 | name = RBSentinelDemo; 301 | productName = RBSentinelDemo; 302 | productReference = FA97C26E1B121BC6008148F9 /* RBSentinelDemo.app */; 303 | productType = "com.apple.product-type.application"; 304 | }; 305 | FA97C2861B121BC6008148F9 /* RBSentinelDemoTests */ = { 306 | isa = PBXNativeTarget; 307 | buildConfigurationList = FA97C2941B121BC6008148F9 /* Build configuration list for PBXNativeTarget "RBSentinelDemoTests" */; 308 | buildPhases = ( 309 | FA97C2831B121BC6008148F9 /* Sources */, 310 | FA97C2841B121BC6008148F9 /* Frameworks */, 311 | FA97C2851B121BC6008148F9 /* Resources */, 312 | ); 313 | buildRules = ( 314 | ); 315 | dependencies = ( 316 | FA97C2891B121BC6008148F9 /* PBXTargetDependency */, 317 | ); 318 | name = RBSentinelDemoTests; 319 | productName = RBSentinelDemoTests; 320 | productReference = FA97C2871B121BC6008148F9 /* RBSentinelDemoTests.xctest */; 321 | productType = "com.apple.product-type.bundle.unit-test"; 322 | }; 323 | FA97C2A21B121C90008148F9 /* RBSentinelDemo WatchKit Extension */ = { 324 | isa = PBXNativeTarget; 325 | buildConfigurationList = FA97C2C41B121C90008148F9 /* Build configuration list for PBXNativeTarget "RBSentinelDemo WatchKit Extension" */; 326 | buildPhases = ( 327 | FA97C29F1B121C90008148F9 /* Sources */, 328 | FA97C2A01B121C90008148F9 /* Frameworks */, 329 | FA97C2A11B121C90008148F9 /* Resources */, 330 | ); 331 | buildRules = ( 332 | ); 333 | dependencies = ( 334 | FA97C2B51B121C90008148F9 /* PBXTargetDependency */, 335 | ); 336 | name = "RBSentinelDemo WatchKit Extension"; 337 | productName = "RBSentinelDemo WatchKit Extension"; 338 | productReference = FA97C2A31B121C90008148F9 /* RBSentinelDemo WatchKit Extension.appex */; 339 | productType = "com.apple.product-type.watchkit-extension"; 340 | }; 341 | FA97C2B11B121C90008148F9 /* RBSentinelDemo WatchKit App */ = { 342 | isa = PBXNativeTarget; 343 | buildConfigurationList = FA97C2C11B121C90008148F9 /* Build configuration list for PBXNativeTarget "RBSentinelDemo WatchKit App" */; 344 | buildPhases = ( 345 | FA97C2B01B121C90008148F9 /* Resources */, 346 | ); 347 | buildRules = ( 348 | ); 349 | dependencies = ( 350 | ); 351 | name = "RBSentinelDemo WatchKit App"; 352 | productName = "RBSentinelDemo WatchKit App"; 353 | productReference = FA97C2B21B121C90008148F9 /* RBSentinelDemo WatchKit App.app */; 354 | productType = "com.apple.product-type.application.watchapp"; 355 | }; 356 | /* End PBXNativeTarget section */ 357 | 358 | /* Begin PBXProject section */ 359 | FA97C2661B121BC5008148F9 /* Project object */ = { 360 | isa = PBXProject; 361 | attributes = { 362 | LastUpgradeCheck = 0630; 363 | ORGANIZATIONNAME = "Roshan Nindrai Senthilnathan"; 364 | TargetAttributes = { 365 | FA97C26D1B121BC6008148F9 = { 366 | CreatedOnToolsVersion = 6.3.1; 367 | DevelopmentTeam = W2MHQ39N9M; 368 | SystemCapabilities = { 369 | com.apple.ApplicationGroups.iOS = { 370 | enabled = 1; 371 | }; 372 | }; 373 | }; 374 | FA97C2861B121BC6008148F9 = { 375 | CreatedOnToolsVersion = 6.3.1; 376 | TestTargetID = FA97C26D1B121BC6008148F9; 377 | }; 378 | FA97C2A21B121C90008148F9 = { 379 | CreatedOnToolsVersion = 6.3.1; 380 | DevelopmentTeam = W2MHQ39N9M; 381 | SystemCapabilities = { 382 | com.apple.ApplicationGroups.iOS = { 383 | enabled = 1; 384 | }; 385 | }; 386 | }; 387 | FA97C2B11B121C90008148F9 = { 388 | CreatedOnToolsVersion = 6.3.1; 389 | }; 390 | }; 391 | }; 392 | buildConfigurationList = FA97C2691B121BC5008148F9 /* Build configuration list for PBXProject "RBSentinelDemo" */; 393 | compatibilityVersion = "Xcode 3.2"; 394 | developmentRegion = English; 395 | hasScannedForEncodings = 0; 396 | knownRegions = ( 397 | en, 398 | Base, 399 | ); 400 | mainGroup = FA97C2651B121BC5008148F9; 401 | productRefGroup = FA97C26F1B121BC6008148F9 /* Products */; 402 | projectDirPath = ""; 403 | projectRoot = ""; 404 | targets = ( 405 | FA97C26D1B121BC6008148F9 /* RBSentinelDemo */, 406 | FA97C2861B121BC6008148F9 /* RBSentinelDemoTests */, 407 | FA97C2A21B121C90008148F9 /* RBSentinelDemo WatchKit Extension */, 408 | FA97C2B11B121C90008148F9 /* RBSentinelDemo WatchKit App */, 409 | ); 410 | }; 411 | /* End PBXProject section */ 412 | 413 | /* Begin PBXResourcesBuildPhase section */ 414 | FA97C26C1B121BC6008148F9 /* Resources */ = { 415 | isa = PBXResourcesBuildPhase; 416 | buildActionMask = 2147483647; 417 | files = ( 418 | FA97C27D1B121BC6008148F9 /* Main.storyboard in Resources */, 419 | FA97C2821B121BC6008148F9 /* LaunchScreen.xib in Resources */, 420 | FA97C27F1B121BC6008148F9 /* Images.xcassets in Resources */, 421 | ); 422 | runOnlyForDeploymentPostprocessing = 0; 423 | }; 424 | FA97C2851B121BC6008148F9 /* Resources */ = { 425 | isa = PBXResourcesBuildPhase; 426 | buildActionMask = 2147483647; 427 | files = ( 428 | ); 429 | runOnlyForDeploymentPostprocessing = 0; 430 | }; 431 | FA97C2A11B121C90008148F9 /* Resources */ = { 432 | isa = PBXResourcesBuildPhase; 433 | buildActionMask = 2147483647; 434 | files = ( 435 | FA97C2AF1B121C90008148F9 /* Images.xcassets in Resources */, 436 | FA97C2B31B121C90008148F9 /* RBSentinelDemo WatchKit App.app in Resources */, 437 | ); 438 | runOnlyForDeploymentPostprocessing = 0; 439 | }; 440 | FA97C2B01B121C90008148F9 /* Resources */ = { 441 | isa = PBXResourcesBuildPhase; 442 | buildActionMask = 2147483647; 443 | files = ( 444 | FA97C2BB1B121C90008148F9 /* Interface.storyboard in Resources */, 445 | FA97C2BD1B121C90008148F9 /* Images.xcassets in Resources */, 446 | ); 447 | runOnlyForDeploymentPostprocessing = 0; 448 | }; 449 | /* End PBXResourcesBuildPhase section */ 450 | 451 | /* Begin PBXSourcesBuildPhase section */ 452 | FA97C26A1B121BC6008148F9 /* Sources */ = { 453 | isa = PBXSourcesBuildPhase; 454 | buildActionMask = 2147483647; 455 | files = ( 456 | FA97C2CB1B121D86008148F9 /* PostHandler.m in Sources */, 457 | FA97C27A1B121BC6008148F9 /* ViewController.m in Sources */, 458 | FA97C2771B121BC6008148F9 /* AppDelegate.m in Sources */, 459 | FA97C2741B121BC6008148F9 /* main.m in Sources */, 460 | FA97C29E1B121C2C008148F9 /* RBSentinel.m in Sources */, 461 | ); 462 | runOnlyForDeploymentPostprocessing = 0; 463 | }; 464 | FA97C2831B121BC6008148F9 /* Sources */ = { 465 | isa = PBXSourcesBuildPhase; 466 | buildActionMask = 2147483647; 467 | files = ( 468 | FA97C28E1B121BC6008148F9 /* RBSentinelDemoTests.m in Sources */, 469 | ); 470 | runOnlyForDeploymentPostprocessing = 0; 471 | }; 472 | FA97C29F1B121C90008148F9 /* Sources */ = { 473 | isa = PBXSourcesBuildPhase; 474 | buildActionMask = 2147483647; 475 | files = ( 476 | FA97C2CC1B121DAD008148F9 /* RBSentinel.m in Sources */, 477 | FA97C2AD1B121C90008148F9 /* NotificationController.m in Sources */, 478 | FA97C2AA1B121C90008148F9 /* InterfaceController.m in Sources */, 479 | ); 480 | runOnlyForDeploymentPostprocessing = 0; 481 | }; 482 | /* End PBXSourcesBuildPhase section */ 483 | 484 | /* Begin PBXTargetDependency section */ 485 | FA97C2891B121BC6008148F9 /* PBXTargetDependency */ = { 486 | isa = PBXTargetDependency; 487 | target = FA97C26D1B121BC6008148F9 /* RBSentinelDemo */; 488 | targetProxy = FA97C2881B121BC6008148F9 /* PBXContainerItemProxy */; 489 | }; 490 | FA97C2B51B121C90008148F9 /* PBXTargetDependency */ = { 491 | isa = PBXTargetDependency; 492 | target = FA97C2B11B121C90008148F9 /* RBSentinelDemo WatchKit App */; 493 | targetProxy = FA97C2B41B121C90008148F9 /* PBXContainerItemProxy */; 494 | }; 495 | FA97C2BF1B121C90008148F9 /* PBXTargetDependency */ = { 496 | isa = PBXTargetDependency; 497 | target = FA97C2A21B121C90008148F9 /* RBSentinelDemo WatchKit Extension */; 498 | targetProxy = FA97C2BE1B121C90008148F9 /* PBXContainerItemProxy */; 499 | }; 500 | /* End PBXTargetDependency section */ 501 | 502 | /* Begin PBXVariantGroup section */ 503 | FA97C27B1B121BC6008148F9 /* Main.storyboard */ = { 504 | isa = PBXVariantGroup; 505 | children = ( 506 | FA97C27C1B121BC6008148F9 /* Base */, 507 | ); 508 | name = Main.storyboard; 509 | path = .; 510 | sourceTree = ""; 511 | }; 512 | FA97C2801B121BC6008148F9 /* LaunchScreen.xib */ = { 513 | isa = PBXVariantGroup; 514 | children = ( 515 | FA97C2811B121BC6008148F9 /* Base */, 516 | ); 517 | name = LaunchScreen.xib; 518 | path = .; 519 | sourceTree = ""; 520 | }; 521 | FA97C2B91B121C90008148F9 /* Interface.storyboard */ = { 522 | isa = PBXVariantGroup; 523 | children = ( 524 | FA97C2BA1B121C90008148F9 /* Base */, 525 | ); 526 | name = Interface.storyboard; 527 | path = .; 528 | sourceTree = ""; 529 | }; 530 | /* End PBXVariantGroup section */ 531 | 532 | /* Begin XCBuildConfiguration section */ 533 | FA97C28F1B121BC6008148F9 /* Debug */ = { 534 | isa = XCBuildConfiguration; 535 | buildSettings = { 536 | ALWAYS_SEARCH_USER_PATHS = NO; 537 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 538 | CLANG_CXX_LIBRARY = "libc++"; 539 | CLANG_ENABLE_MODULES = YES; 540 | CLANG_ENABLE_OBJC_ARC = YES; 541 | CLANG_WARN_BOOL_CONVERSION = YES; 542 | CLANG_WARN_CONSTANT_CONVERSION = YES; 543 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 544 | CLANG_WARN_EMPTY_BODY = YES; 545 | CLANG_WARN_ENUM_CONVERSION = YES; 546 | CLANG_WARN_INT_CONVERSION = YES; 547 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 548 | CLANG_WARN_UNREACHABLE_CODE = YES; 549 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 550 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 551 | COPY_PHASE_STRIP = NO; 552 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 553 | ENABLE_STRICT_OBJC_MSGSEND = YES; 554 | GCC_C_LANGUAGE_STANDARD = gnu99; 555 | GCC_DYNAMIC_NO_PIC = NO; 556 | GCC_NO_COMMON_BLOCKS = YES; 557 | GCC_OPTIMIZATION_LEVEL = 0; 558 | GCC_PREPROCESSOR_DEFINITIONS = ( 559 | "DEBUG=1", 560 | "$(inherited)", 561 | ); 562 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 563 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 564 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 565 | GCC_WARN_UNDECLARED_SELECTOR = YES; 566 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 567 | GCC_WARN_UNUSED_FUNCTION = YES; 568 | GCC_WARN_UNUSED_VARIABLE = YES; 569 | IPHONEOS_DEPLOYMENT_TARGET = 8.3; 570 | MTL_ENABLE_DEBUG_INFO = YES; 571 | ONLY_ACTIVE_ARCH = YES; 572 | SDKROOT = iphoneos; 573 | }; 574 | name = Debug; 575 | }; 576 | FA97C2901B121BC6008148F9 /* Release */ = { 577 | isa = XCBuildConfiguration; 578 | buildSettings = { 579 | ALWAYS_SEARCH_USER_PATHS = NO; 580 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 581 | CLANG_CXX_LIBRARY = "libc++"; 582 | CLANG_ENABLE_MODULES = YES; 583 | CLANG_ENABLE_OBJC_ARC = YES; 584 | CLANG_WARN_BOOL_CONVERSION = YES; 585 | CLANG_WARN_CONSTANT_CONVERSION = YES; 586 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 587 | CLANG_WARN_EMPTY_BODY = YES; 588 | CLANG_WARN_ENUM_CONVERSION = YES; 589 | CLANG_WARN_INT_CONVERSION = YES; 590 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 591 | CLANG_WARN_UNREACHABLE_CODE = YES; 592 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 593 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 594 | COPY_PHASE_STRIP = NO; 595 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 596 | ENABLE_NS_ASSERTIONS = NO; 597 | ENABLE_STRICT_OBJC_MSGSEND = YES; 598 | GCC_C_LANGUAGE_STANDARD = gnu99; 599 | GCC_NO_COMMON_BLOCKS = YES; 600 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 601 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 602 | GCC_WARN_UNDECLARED_SELECTOR = YES; 603 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 604 | GCC_WARN_UNUSED_FUNCTION = YES; 605 | GCC_WARN_UNUSED_VARIABLE = YES; 606 | IPHONEOS_DEPLOYMENT_TARGET = 8.3; 607 | MTL_ENABLE_DEBUG_INFO = NO; 608 | SDKROOT = iphoneos; 609 | VALIDATE_PRODUCT = YES; 610 | }; 611 | name = Release; 612 | }; 613 | FA97C2921B121BC6008148F9 /* Debug */ = { 614 | isa = XCBuildConfiguration; 615 | buildSettings = { 616 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 617 | CODE_SIGN_ENTITLEMENTS = RBSentinelDemo/RBSentinelDemo.entitlements; 618 | CODE_SIGN_IDENTITY = "iPhone Developer"; 619 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 620 | INFOPLIST_FILE = "RBSentinelDemo/Supporting Files/Info.plist"; 621 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 622 | PRODUCT_NAME = "$(TARGET_NAME)"; 623 | PROVISIONING_PROFILE = ""; 624 | }; 625 | name = Debug; 626 | }; 627 | FA97C2931B121BC6008148F9 /* Release */ = { 628 | isa = XCBuildConfiguration; 629 | buildSettings = { 630 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 631 | CODE_SIGN_ENTITLEMENTS = RBSentinelDemo/RBSentinelDemo.entitlements; 632 | CODE_SIGN_IDENTITY = "iPhone Developer"; 633 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 634 | INFOPLIST_FILE = "RBSentinelDemo/Supporting Files/Info.plist"; 635 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 636 | PRODUCT_NAME = "$(TARGET_NAME)"; 637 | PROVISIONING_PROFILE = ""; 638 | }; 639 | name = Release; 640 | }; 641 | FA97C2951B121BC6008148F9 /* Debug */ = { 642 | isa = XCBuildConfiguration; 643 | buildSettings = { 644 | BUNDLE_LOADER = "$(TEST_HOST)"; 645 | FRAMEWORK_SEARCH_PATHS = ( 646 | "$(SDKROOT)/Developer/Library/Frameworks", 647 | "$(inherited)", 648 | ); 649 | GCC_PREPROCESSOR_DEFINITIONS = ( 650 | "DEBUG=1", 651 | "$(inherited)", 652 | ); 653 | INFOPLIST_FILE = "RBSentinelDemoTests/Supporting Files/Info.plist"; 654 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 655 | PRODUCT_NAME = "$(TARGET_NAME)"; 656 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/RBSentinelDemo.app/RBSentinelDemo"; 657 | }; 658 | name = Debug; 659 | }; 660 | FA97C2961B121BC6008148F9 /* Release */ = { 661 | isa = XCBuildConfiguration; 662 | buildSettings = { 663 | BUNDLE_LOADER = "$(TEST_HOST)"; 664 | FRAMEWORK_SEARCH_PATHS = ( 665 | "$(SDKROOT)/Developer/Library/Frameworks", 666 | "$(inherited)", 667 | ); 668 | INFOPLIST_FILE = "RBSentinelDemoTests/Supporting Files/Info.plist"; 669 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 670 | PRODUCT_NAME = "$(TARGET_NAME)"; 671 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/RBSentinelDemo.app/RBSentinelDemo"; 672 | }; 673 | name = Release; 674 | }; 675 | FA97C2C21B121C90008148F9 /* Debug */ = { 676 | isa = XCBuildConfiguration; 677 | buildSettings = { 678 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 679 | GCC_PREPROCESSOR_DEFINITIONS = ( 680 | "DEBUG=1", 681 | "$(inherited)", 682 | ); 683 | IBSC_MODULE = RBSentinelDemo_WatchKit_Extension; 684 | INFOPLIST_FILE = "RBSentinelDemo WatchKit App/Supporting Files/Info.plist"; 685 | IPHONEOS_DEPLOYMENT_TARGET = 8.2; 686 | PRODUCT_NAME = "$(TARGET_NAME)"; 687 | SKIP_INSTALL = YES; 688 | TARGETED_DEVICE_FAMILY = 4; 689 | "TARGETED_DEVICE_FAMILY[sdk=iphonesimulator*]" = "1,4"; 690 | }; 691 | name = Debug; 692 | }; 693 | FA97C2C31B121C90008148F9 /* Release */ = { 694 | isa = XCBuildConfiguration; 695 | buildSettings = { 696 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 697 | IBSC_MODULE = RBSentinelDemo_WatchKit_Extension; 698 | INFOPLIST_FILE = "RBSentinelDemo WatchKit App/Supporting Files/Info.plist"; 699 | IPHONEOS_DEPLOYMENT_TARGET = 8.2; 700 | PRODUCT_NAME = "$(TARGET_NAME)"; 701 | SKIP_INSTALL = YES; 702 | TARGETED_DEVICE_FAMILY = 4; 703 | "TARGETED_DEVICE_FAMILY[sdk=iphonesimulator*]" = "1,4"; 704 | }; 705 | name = Release; 706 | }; 707 | FA97C2C51B121C90008148F9 /* Debug */ = { 708 | isa = XCBuildConfiguration; 709 | buildSettings = { 710 | CODE_SIGN_ENTITLEMENTS = "RBSentinelDemo WatchKit Extension/RBSentinelDemo WatchKit Extension.entitlements"; 711 | CODE_SIGN_IDENTITY = "iPhone Developer"; 712 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 713 | GCC_PREPROCESSOR_DEFINITIONS = ( 714 | "DEBUG=1", 715 | "$(inherited)", 716 | ); 717 | INFOPLIST_FILE = "RBSentinelDemo WatchKit Extension/Supporting Files/Info.plist"; 718 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; 719 | PRODUCT_NAME = "${TARGET_NAME}"; 720 | PROVISIONING_PROFILE = ""; 721 | SKIP_INSTALL = YES; 722 | }; 723 | name = Debug; 724 | }; 725 | FA97C2C61B121C90008148F9 /* Release */ = { 726 | isa = XCBuildConfiguration; 727 | buildSettings = { 728 | CODE_SIGN_ENTITLEMENTS = "RBSentinelDemo WatchKit Extension/RBSentinelDemo WatchKit Extension.entitlements"; 729 | CODE_SIGN_IDENTITY = "iPhone Developer"; 730 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 731 | INFOPLIST_FILE = "RBSentinelDemo WatchKit Extension/Supporting Files/Info.plist"; 732 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; 733 | PRODUCT_NAME = "${TARGET_NAME}"; 734 | PROVISIONING_PROFILE = ""; 735 | SKIP_INSTALL = YES; 736 | }; 737 | name = Release; 738 | }; 739 | /* End XCBuildConfiguration section */ 740 | 741 | /* Begin XCConfigurationList section */ 742 | FA97C2691B121BC5008148F9 /* Build configuration list for PBXProject "RBSentinelDemo" */ = { 743 | isa = XCConfigurationList; 744 | buildConfigurations = ( 745 | FA97C28F1B121BC6008148F9 /* Debug */, 746 | FA97C2901B121BC6008148F9 /* Release */, 747 | ); 748 | defaultConfigurationIsVisible = 0; 749 | defaultConfigurationName = Release; 750 | }; 751 | FA97C2911B121BC6008148F9 /* Build configuration list for PBXNativeTarget "RBSentinelDemo" */ = { 752 | isa = XCConfigurationList; 753 | buildConfigurations = ( 754 | FA97C2921B121BC6008148F9 /* Debug */, 755 | FA97C2931B121BC6008148F9 /* Release */, 756 | ); 757 | defaultConfigurationIsVisible = 0; 758 | defaultConfigurationName = Release; 759 | }; 760 | FA97C2941B121BC6008148F9 /* Build configuration list for PBXNativeTarget "RBSentinelDemoTests" */ = { 761 | isa = XCConfigurationList; 762 | buildConfigurations = ( 763 | FA97C2951B121BC6008148F9 /* Debug */, 764 | FA97C2961B121BC6008148F9 /* Release */, 765 | ); 766 | defaultConfigurationIsVisible = 0; 767 | defaultConfigurationName = Release; 768 | }; 769 | FA97C2C11B121C90008148F9 /* Build configuration list for PBXNativeTarget "RBSentinelDemo WatchKit App" */ = { 770 | isa = XCConfigurationList; 771 | buildConfigurations = ( 772 | FA97C2C21B121C90008148F9 /* Debug */, 773 | FA97C2C31B121C90008148F9 /* Release */, 774 | ); 775 | defaultConfigurationIsVisible = 0; 776 | defaultConfigurationName = Release; 777 | }; 778 | FA97C2C41B121C90008148F9 /* Build configuration list for PBXNativeTarget "RBSentinelDemo WatchKit Extension" */ = { 779 | isa = XCConfigurationList; 780 | buildConfigurations = ( 781 | FA97C2C51B121C90008148F9 /* Debug */, 782 | FA97C2C61B121C90008148F9 /* Release */, 783 | ); 784 | defaultConfigurationIsVisible = 0; 785 | defaultConfigurationName = Release; 786 | }; 787 | /* End XCConfigurationList section */ 788 | }; 789 | rootObject = FA97C2661B121BC5008148F9 /* Project object */; 790 | } 791 | --------------------------------------------------------------------------------