├── .gitignore ├── AppleRemote ├── AppleRemote.xcodeproj │ └── project.pbxproj └── AppleRemote │ ├── AppleRemote.h │ ├── AppleRemote.m │ ├── AppleRemoteMapping.map │ ├── Info.plist │ └── Internal Classes │ ├── HIDRemoteControlDevice.h │ ├── HIDRemoteControlDevice.m │ ├── RemoteControl.h │ └── RemoteControl.m ├── Demos ├── ObjC │ └── Apple Remote Demo │ │ ├── Apple Remote Demo.xcodeproj │ │ └── project.pbxproj │ │ ├── Apple Remote Demo │ │ ├── AppDelegate.h │ │ ├── AppDelegate.m │ │ ├── Base.lproj │ │ │ └── MainMenu.xib │ │ ├── Images.xcassets │ │ │ └── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ ├── Info.plist │ │ └── main.m │ │ └── resources │ │ ├── AppleRemote.pcvd │ │ └── AppleRemoteUnavailable.pcvd ├── Swift │ └── Apple Remote Swift Demo │ │ ├── Apple Remote Swift Demo.xcodeproj │ │ └── project.pbxproj │ │ └── Apple Remote Swift Demo │ │ ├── AppDelegate.swift │ │ ├── Base.lproj │ │ └── MainMenu.xib │ │ ├── Images.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Info.plist └── shared │ └── AppleRemoteSimulator │ ├── AppleRemoteSimulator.xcodeproj │ └── project.pbxproj │ └── AppleRemoteSimulator │ ├── AppleRemoteSimulator.h │ ├── Info.plist │ ├── RSAppleRemoteDeviceView.h │ ├── RSAppleRemoteDeviceView.m │ ├── RSRemoteDeviceSimulatorWindow.h │ └── RSRemoteDeviceSimulatorWindow.m ├── LICENSE ├── README.md └── screenshot.png /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | __MACOSX 3 | *.pbxuser 4 | !default.pbxuser 5 | *.mode1v3 6 | !default.mode1v3 7 | *.mode2v3 8 | !default.mode2v3 9 | *.perspectivev3 10 | !default.perspectivev3 11 | *.xcworkspace 12 | !default.xcworkspace 13 | xcuserdata 14 | profile 15 | *.moved-aside 16 | DerivedData 17 | .idea/ -------------------------------------------------------------------------------- /AppleRemote/AppleRemote.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | DDB6D75B1A64599C003B6EEA /* AppleRemote.h in Headers */ = {isa = PBXBuildFile; fileRef = DDB6D75A1A64599C003B6EEA /* AppleRemote.h */; settings = {ATTRIBUTES = (Public, ); }; }; 11 | DDB6D7AE1A645A6F003B6EEA /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DDB6D7AB1A645A60003B6EEA /* IOKit.framework */; }; 12 | DDB6D7B41A645AF5003B6EEA /* HIDRemoteControlDevice.h in Headers */ = {isa = PBXBuildFile; fileRef = DDB6D7B01A645AF5003B6EEA /* HIDRemoteControlDevice.h */; settings = {ATTRIBUTES = (Public, ); }; }; 13 | DDB6D7B51A645AF5003B6EEA /* HIDRemoteControlDevice.m in Sources */ = {isa = PBXBuildFile; fileRef = DDB6D7B11A645AF5003B6EEA /* HIDRemoteControlDevice.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; 14 | DDB6D7B61A645AF5003B6EEA /* RemoteControl.h in Headers */ = {isa = PBXBuildFile; fileRef = DDB6D7B21A645AF5003B6EEA /* RemoteControl.h */; settings = {ATTRIBUTES = (Public, ); }; }; 15 | DDB6D7B71A645AF5003B6EEA /* RemoteControl.m in Sources */ = {isa = PBXBuildFile; fileRef = DDB6D7B31A645AF5003B6EEA /* RemoteControl.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; 16 | DDB6D7B91A645B4D003B6EEA /* AppleRemote.m in Sources */ = {isa = PBXBuildFile; fileRef = DDB6D7B81A645B4D003B6EEA /* AppleRemote.m */; }; 17 | DDB6D7BC1A645D52003B6EEA /* AppleRemoteMapping.map in Resources */ = {isa = PBXBuildFile; fileRef = DDB6D7BA1A645CD4003B6EEA /* AppleRemoteMapping.map */; }; 18 | /* End PBXBuildFile section */ 19 | 20 | /* Begin PBXFileReference section */ 21 | DDB6D7551A64599C003B6EEA /* AppleRemote.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = AppleRemote.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 22 | DDB6D7591A64599C003B6EEA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 23 | DDB6D75A1A64599C003B6EEA /* AppleRemote.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppleRemote.h; sourceTree = ""; }; 24 | DDB6D7AB1A645A60003B6EEA /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; }; 25 | DDB6D7B01A645AF5003B6EEA /* HIDRemoteControlDevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HIDRemoteControlDevice.h; sourceTree = ""; }; 26 | DDB6D7B11A645AF5003B6EEA /* HIDRemoteControlDevice.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HIDRemoteControlDevice.m; sourceTree = ""; }; 27 | DDB6D7B21A645AF5003B6EEA /* RemoteControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RemoteControl.h; sourceTree = ""; }; 28 | DDB6D7B31A645AF5003B6EEA /* RemoteControl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RemoteControl.m; sourceTree = ""; }; 29 | DDB6D7B81A645B4D003B6EEA /* AppleRemote.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppleRemote.m; sourceTree = ""; }; 30 | DDB6D7BA1A645CD4003B6EEA /* AppleRemoteMapping.map */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = "sourcecode.module-map"; path = AppleRemoteMapping.map; sourceTree = ""; }; 31 | /* End PBXFileReference section */ 32 | 33 | /* Begin PBXFrameworksBuildPhase section */ 34 | DDB6D7511A64599C003B6EEA /* Frameworks */ = { 35 | isa = PBXFrameworksBuildPhase; 36 | buildActionMask = 2147483647; 37 | files = ( 38 | DDB6D7AE1A645A6F003B6EEA /* IOKit.framework in Frameworks */, 39 | ); 40 | runOnlyForDeploymentPostprocessing = 0; 41 | }; 42 | /* End PBXFrameworksBuildPhase section */ 43 | 44 | /* Begin PBXGroup section */ 45 | DDB6D74B1A64599C003B6EEA = { 46 | isa = PBXGroup; 47 | children = ( 48 | DDB6D7AD1A645A67003B6EEA /* Frameworks */, 49 | DDB6D7571A64599C003B6EEA /* AppleRemote */, 50 | DDB6D7561A64599C003B6EEA /* Products */, 51 | ); 52 | sourceTree = ""; 53 | }; 54 | DDB6D7561A64599C003B6EEA /* Products */ = { 55 | isa = PBXGroup; 56 | children = ( 57 | DDB6D7551A64599C003B6EEA /* AppleRemote.framework */, 58 | ); 59 | name = Products; 60 | sourceTree = ""; 61 | }; 62 | DDB6D7571A64599C003B6EEA /* AppleRemote */ = { 63 | isa = PBXGroup; 64 | children = ( 65 | DDB6D7AF1A645ABD003B6EEA /* Internal Classes */, 66 | DDB6D75A1A64599C003B6EEA /* AppleRemote.h */, 67 | DDB6D7581A64599C003B6EEA /* Supporting Files */, 68 | DDB6D7B81A645B4D003B6EEA /* AppleRemote.m */, 69 | ); 70 | path = AppleRemote; 71 | sourceTree = ""; 72 | }; 73 | DDB6D7581A64599C003B6EEA /* Supporting Files */ = { 74 | isa = PBXGroup; 75 | children = ( 76 | DDB6D7BA1A645CD4003B6EEA /* AppleRemoteMapping.map */, 77 | DDB6D7591A64599C003B6EEA /* Info.plist */, 78 | ); 79 | name = "Supporting Files"; 80 | sourceTree = ""; 81 | }; 82 | DDB6D7AD1A645A67003B6EEA /* Frameworks */ = { 83 | isa = PBXGroup; 84 | children = ( 85 | DDB6D7AB1A645A60003B6EEA /* IOKit.framework */, 86 | ); 87 | name = Frameworks; 88 | sourceTree = ""; 89 | }; 90 | DDB6D7AF1A645ABD003B6EEA /* Internal Classes */ = { 91 | isa = PBXGroup; 92 | children = ( 93 | DDB6D7B01A645AF5003B6EEA /* HIDRemoteControlDevice.h */, 94 | DDB6D7B11A645AF5003B6EEA /* HIDRemoteControlDevice.m */, 95 | DDB6D7B21A645AF5003B6EEA /* RemoteControl.h */, 96 | DDB6D7B31A645AF5003B6EEA /* RemoteControl.m */, 97 | ); 98 | path = "Internal Classes"; 99 | sourceTree = ""; 100 | }; 101 | /* End PBXGroup section */ 102 | 103 | /* Begin PBXHeadersBuildPhase section */ 104 | DDB6D7521A64599C003B6EEA /* Headers */ = { 105 | isa = PBXHeadersBuildPhase; 106 | buildActionMask = 2147483647; 107 | files = ( 108 | DDB6D7B41A645AF5003B6EEA /* HIDRemoteControlDevice.h in Headers */, 109 | DDB6D7B61A645AF5003B6EEA /* RemoteControl.h in Headers */, 110 | DDB6D75B1A64599C003B6EEA /* AppleRemote.h in Headers */, 111 | ); 112 | runOnlyForDeploymentPostprocessing = 0; 113 | }; 114 | /* End PBXHeadersBuildPhase section */ 115 | 116 | /* Begin PBXNativeTarget section */ 117 | DDB6D7541A64599C003B6EEA /* AppleRemote */ = { 118 | isa = PBXNativeTarget; 119 | buildConfigurationList = DDB6D76B1A64599C003B6EEA /* Build configuration list for PBXNativeTarget "AppleRemote" */; 120 | buildPhases = ( 121 | DDB6D7501A64599C003B6EEA /* Sources */, 122 | DDB6D7511A64599C003B6EEA /* Frameworks */, 123 | DDB6D7521A64599C003B6EEA /* Headers */, 124 | DDB6D7531A64599C003B6EEA /* Resources */, 125 | ); 126 | buildRules = ( 127 | ); 128 | dependencies = ( 129 | ); 130 | name = AppleRemote; 131 | productName = AppleRemote; 132 | productReference = DDB6D7551A64599C003B6EEA /* AppleRemote.framework */; 133 | productType = "com.apple.product-type.framework"; 134 | }; 135 | /* End PBXNativeTarget section */ 136 | 137 | /* Begin PBXProject section */ 138 | DDB6D74C1A64599C003B6EEA /* Project object */ = { 139 | isa = PBXProject; 140 | attributes = { 141 | LastUpgradeCheck = 0610; 142 | ORGANIZATIONNAME = "Guilherme Rambo"; 143 | TargetAttributes = { 144 | DDB6D7541A64599C003B6EEA = { 145 | CreatedOnToolsVersion = 6.1.1; 146 | }; 147 | }; 148 | }; 149 | buildConfigurationList = DDB6D74F1A64599C003B6EEA /* Build configuration list for PBXProject "AppleRemote" */; 150 | compatibilityVersion = "Xcode 3.2"; 151 | developmentRegion = English; 152 | hasScannedForEncodings = 0; 153 | knownRegions = ( 154 | en, 155 | ); 156 | mainGroup = DDB6D74B1A64599C003B6EEA; 157 | productRefGroup = DDB6D7561A64599C003B6EEA /* Products */; 158 | projectDirPath = ""; 159 | projectRoot = ""; 160 | targets = ( 161 | DDB6D7541A64599C003B6EEA /* AppleRemote */, 162 | ); 163 | }; 164 | /* End PBXProject section */ 165 | 166 | /* Begin PBXResourcesBuildPhase section */ 167 | DDB6D7531A64599C003B6EEA /* Resources */ = { 168 | isa = PBXResourcesBuildPhase; 169 | buildActionMask = 2147483647; 170 | files = ( 171 | DDB6D7BC1A645D52003B6EEA /* AppleRemoteMapping.map in Resources */, 172 | ); 173 | runOnlyForDeploymentPostprocessing = 0; 174 | }; 175 | /* End PBXResourcesBuildPhase section */ 176 | 177 | /* Begin PBXSourcesBuildPhase section */ 178 | DDB6D7501A64599C003B6EEA /* Sources */ = { 179 | isa = PBXSourcesBuildPhase; 180 | buildActionMask = 2147483647; 181 | files = ( 182 | DDB6D7B51A645AF5003B6EEA /* HIDRemoteControlDevice.m in Sources */, 183 | DDB6D7B91A645B4D003B6EEA /* AppleRemote.m in Sources */, 184 | DDB6D7B71A645AF5003B6EEA /* RemoteControl.m in Sources */, 185 | ); 186 | runOnlyForDeploymentPostprocessing = 0; 187 | }; 188 | /* End PBXSourcesBuildPhase section */ 189 | 190 | /* Begin XCBuildConfiguration section */ 191 | DDB6D7691A64599C003B6EEA /* Debug */ = { 192 | isa = XCBuildConfiguration; 193 | buildSettings = { 194 | ALWAYS_SEARCH_USER_PATHS = NO; 195 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 196 | CLANG_CXX_LIBRARY = "libc++"; 197 | CLANG_ENABLE_MODULES = YES; 198 | CLANG_ENABLE_OBJC_ARC = YES; 199 | CLANG_WARN_BOOL_CONVERSION = YES; 200 | CLANG_WARN_CONSTANT_CONVERSION = YES; 201 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 202 | CLANG_WARN_EMPTY_BODY = YES; 203 | CLANG_WARN_ENUM_CONVERSION = YES; 204 | CLANG_WARN_INT_CONVERSION = YES; 205 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 206 | CLANG_WARN_UNREACHABLE_CODE = YES; 207 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 208 | COPY_PHASE_STRIP = NO; 209 | CURRENT_PROJECT_VERSION = 1; 210 | ENABLE_STRICT_OBJC_MSGSEND = YES; 211 | GCC_C_LANGUAGE_STANDARD = gnu99; 212 | GCC_DYNAMIC_NO_PIC = NO; 213 | GCC_OPTIMIZATION_LEVEL = 0; 214 | GCC_PREPROCESSOR_DEFINITIONS = ( 215 | "DEBUG=1", 216 | "$(inherited)", 217 | ); 218 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 219 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 220 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 221 | GCC_WARN_UNDECLARED_SELECTOR = YES; 222 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 223 | GCC_WARN_UNUSED_FUNCTION = YES; 224 | GCC_WARN_UNUSED_VARIABLE = YES; 225 | MACOSX_DEPLOYMENT_TARGET = 10.10; 226 | MTL_ENABLE_DEBUG_INFO = YES; 227 | ONLY_ACTIVE_ARCH = YES; 228 | SDKROOT = macosx; 229 | VERSIONING_SYSTEM = "apple-generic"; 230 | VERSION_INFO_PREFIX = ""; 231 | }; 232 | name = Debug; 233 | }; 234 | DDB6D76A1A64599C003B6EEA /* Release */ = { 235 | isa = XCBuildConfiguration; 236 | buildSettings = { 237 | ALWAYS_SEARCH_USER_PATHS = NO; 238 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 239 | CLANG_CXX_LIBRARY = "libc++"; 240 | CLANG_ENABLE_MODULES = YES; 241 | CLANG_ENABLE_OBJC_ARC = YES; 242 | CLANG_WARN_BOOL_CONVERSION = YES; 243 | CLANG_WARN_CONSTANT_CONVERSION = YES; 244 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 245 | CLANG_WARN_EMPTY_BODY = YES; 246 | CLANG_WARN_ENUM_CONVERSION = YES; 247 | CLANG_WARN_INT_CONVERSION = YES; 248 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 249 | CLANG_WARN_UNREACHABLE_CODE = YES; 250 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 251 | COPY_PHASE_STRIP = YES; 252 | CURRENT_PROJECT_VERSION = 1; 253 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 254 | ENABLE_NS_ASSERTIONS = NO; 255 | ENABLE_STRICT_OBJC_MSGSEND = YES; 256 | GCC_C_LANGUAGE_STANDARD = gnu99; 257 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 258 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 259 | GCC_WARN_UNDECLARED_SELECTOR = YES; 260 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 261 | GCC_WARN_UNUSED_FUNCTION = YES; 262 | GCC_WARN_UNUSED_VARIABLE = YES; 263 | MACOSX_DEPLOYMENT_TARGET = 10.10; 264 | MTL_ENABLE_DEBUG_INFO = NO; 265 | SDKROOT = macosx; 266 | VERSIONING_SYSTEM = "apple-generic"; 267 | VERSION_INFO_PREFIX = ""; 268 | }; 269 | name = Release; 270 | }; 271 | DDB6D76C1A64599C003B6EEA /* Debug */ = { 272 | isa = XCBuildConfiguration; 273 | buildSettings = { 274 | COMBINE_HIDPI_IMAGES = YES; 275 | DEFINES_MODULE = YES; 276 | DYLIB_COMPATIBILITY_VERSION = 1; 277 | DYLIB_CURRENT_VERSION = 1; 278 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 279 | FRAMEWORK_VERSION = A; 280 | INFOPLIST_FILE = AppleRemote/Info.plist; 281 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 282 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; 283 | PRODUCT_NAME = "$(TARGET_NAME)"; 284 | SKIP_INSTALL = YES; 285 | }; 286 | name = Debug; 287 | }; 288 | DDB6D76D1A64599C003B6EEA /* Release */ = { 289 | isa = XCBuildConfiguration; 290 | buildSettings = { 291 | COMBINE_HIDPI_IMAGES = YES; 292 | DEFINES_MODULE = YES; 293 | DYLIB_COMPATIBILITY_VERSION = 1; 294 | DYLIB_CURRENT_VERSION = 1; 295 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 296 | FRAMEWORK_VERSION = A; 297 | INFOPLIST_FILE = AppleRemote/Info.plist; 298 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 299 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; 300 | PRODUCT_NAME = "$(TARGET_NAME)"; 301 | SKIP_INSTALL = YES; 302 | }; 303 | name = Release; 304 | }; 305 | /* End XCBuildConfiguration section */ 306 | 307 | /* Begin XCConfigurationList section */ 308 | DDB6D74F1A64599C003B6EEA /* Build configuration list for PBXProject "AppleRemote" */ = { 309 | isa = XCConfigurationList; 310 | buildConfigurations = ( 311 | DDB6D7691A64599C003B6EEA /* Debug */, 312 | DDB6D76A1A64599C003B6EEA /* Release */, 313 | ); 314 | defaultConfigurationIsVisible = 0; 315 | defaultConfigurationName = Release; 316 | }; 317 | DDB6D76B1A64599C003B6EEA /* Build configuration list for PBXNativeTarget "AppleRemote" */ = { 318 | isa = XCConfigurationList; 319 | buildConfigurations = ( 320 | DDB6D76C1A64599C003B6EEA /* Debug */, 321 | DDB6D76D1A64599C003B6EEA /* Release */, 322 | ); 323 | defaultConfigurationIsVisible = 0; 324 | defaultConfigurationName = Release; 325 | }; 326 | /* End XCConfigurationList section */ 327 | }; 328 | rootObject = DDB6D74C1A64599C003B6EEA /* Project object */; 329 | } 330 | -------------------------------------------------------------------------------- /AppleRemote/AppleRemote/AppleRemote.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppleRemote.h 3 | // AppleRemote 4 | // 5 | // Created by Guilherme Rambo on 12/01/15. 6 | // Copyright (c) 2015 Guilherme Rambo. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for AppleRemote. 12 | FOUNDATION_EXPORT double AppleRemoteVersionNumber; 13 | 14 | //! Project version string for AppleRemote. 15 | FOUNDATION_EXPORT const unsigned char AppleRemoteVersionString[]; 16 | 17 | #import "HIDRemoteControlDevice.h" 18 | 19 | /*! 20 | @typedef Remote listening modes 21 | @constant AppleRemoteListenWhenActiveApp 22 | @constant AppleRemoteListenAlways 23 | */ 24 | typedef NS_ENUM(int, AppleRemoteListeningMode){ 25 | /// The remote events are captured only if the app is active 26 | AppleRemoteListenWhenActiveApp, 27 | 28 | /// The remote events are captured even when the app is inactive 29 | AppleRemoteListenAlways 30 | }; 31 | 32 | @interface AppleRemote : NSObject 33 | 34 | /*! 35 | @brief Returns an AppleRemote instance 36 | @discussion 37 | This returns an AppleRemote instance which you can use to listen to Apple Remote events 38 | * @warning Don't forget to set the pressEventReceiver and releaseEventReceiver blocks 39 | */ 40 | + (AppleRemote *)remoteWithListeningMode:(AppleRemoteListeningMode)mode; 41 | 42 | /*! 43 | @brief The remote's listening mode 44 | */ 45 | @property (nonatomic, assign) AppleRemoteListeningMode listeningMode; 46 | 47 | /*! 48 | @brief Returns YES if infrared is available 49 | */ 50 | + (BOOL)isRemoteAvailable; 51 | 52 | /*! 53 | @brief A block to be executed when a remote control button is pressed 54 | */ 55 | @property (nonatomic, copy) void(^pressEventReceiver)(RemoteControlEventIdentifier eventId); 56 | 57 | /*! 58 | @brief A block to be executed when a remote control button is released 59 | @warning The Play/Pause, Menu and Enter buttons don't have a "released" event 60 | */ 61 | @property (nonatomic, copy) void(^releaseEventReceiver)(RemoteControlEventIdentifier eventId); 62 | 63 | @end -------------------------------------------------------------------------------- /AppleRemote/AppleRemote/AppleRemote.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppleRemote.m 3 | // AppleRemote 4 | // 5 | // Created by Guilherme Rambo on 12/01/15. 6 | // Copyright (c) 2015 Guilherme Rambo. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import 12 | #import 13 | #import 14 | #import 15 | #import 16 | 17 | const char *kAppleRemoteDeviceName = "AppleIRController"; 18 | 19 | @interface AppleRemoteInternal : HIDRemoteControlDevice 20 | @end 21 | 22 | @interface AppleRemoteInternalDelegate : NSObject 23 | 24 | @property (assign) AppleRemote *remote; 25 | 26 | @end 27 | 28 | @interface AppleRemote () 29 | 30 | @property (strong) AppleRemoteInternal *internal; 31 | 32 | @end 33 | 34 | @implementation AppleRemote 35 | 36 | - (instancetype)initWithInternalRemoteDelegate:(id)delegate 37 | { 38 | self = [super init]; 39 | 40 | self.internal = [[AppleRemoteInternal alloc] initWithDelegate:delegate]; 41 | 42 | return self; 43 | } 44 | 45 | + (AppleRemote *)remoteWithListeningMode:(AppleRemoteListeningMode)mode 46 | { 47 | AppleRemote *_instance; 48 | AppleRemoteInternalDelegate *_delegate; 49 | 50 | _delegate = [[AppleRemoteInternalDelegate alloc] init]; 51 | _instance = [[AppleRemote alloc] initWithInternalRemoteDelegate:_delegate]; 52 | _delegate.remote = _instance; 53 | _instance.listeningMode = mode; 54 | 55 | return _instance; 56 | } 57 | 58 | - (void)setListeningMode:(AppleRemoteListeningMode)listeningMode 59 | { 60 | _listeningMode = listeningMode; 61 | 62 | if (_listeningMode == AppleRemoteListenWhenActiveApp) { 63 | [[NSNotificationCenter defaultCenter] addObserverForName:NSApplicationDidBecomeActiveNotification object:NSApp queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) { 64 | [_internal startListening:nil]; 65 | }]; 66 | [[NSNotificationCenter defaultCenter] addObserverForName:NSApplicationDidResignActiveNotification object:NSApp queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) { 67 | [_internal stopListening:nil]; 68 | }]; 69 | } else { 70 | [[NSNotificationCenter defaultCenter] removeObserver:self name:NSApplicationDidBecomeActiveNotification object:NSApp]; 71 | [[NSNotificationCenter defaultCenter] removeObserver:self name:NSApplicationDidResignActiveNotification object:NSApp]; 72 | [_internal startListening:nil]; 73 | } 74 | } 75 | 76 | + (BOOL)isRemoteAvailable 77 | { 78 | return [HIDRemoteControlDevice isRemoteAvailable]; 79 | } 80 | 81 | @end 82 | 83 | @implementation AppleRemoteInternal 84 | 85 | + (const char *)remoteControlDeviceName 86 | { 87 | return kAppleRemoteDeviceName; 88 | } 89 | 90 | - (void)setCookieMappingInDictionary:(NSMutableDictionary*)_cookieToButtonMapping 91 | { 92 | NSMutableDictionary *dict = [NSUnarchiver unarchiveObjectWithFile:[[NSBundle bundleForClass:[self class]] pathForResource:@"AppleRemoteMapping" ofType:@"map"]]; 93 | for (NSString *key in dict.allKeys) { 94 | _cookieToButtonMapping[key] = dict[key]; 95 | } 96 | } 97 | 98 | - (void)sendRemoteButtonEvent:(RemoteControlEventIdentifier)event pressedDown:(BOOL)pressedDown 99 | { 100 | [super sendRemoteButtonEvent:event pressedDown:pressedDown]; 101 | } 102 | 103 | @end 104 | 105 | @implementation AppleRemoteInternalDelegate 106 | 107 | - (void)sendRemoteButtonEvent:(RemoteControlEventIdentifier)event pressedDown:(BOOL)pressedDown remoteControl:(RemoteControl *)remoteControl 108 | { 109 | if (pressedDown) { 110 | if (self.remote.pressEventReceiver) { 111 | self.remote.pressEventReceiver(event); 112 | } else { 113 | NSLog(@"[AppleRemote] WARNING: an Apple Remote event occurred but the pressEventReceiver is not set."); 114 | } 115 | } else { 116 | if (self.remote.releaseEventReceiver) { 117 | self.remote.releaseEventReceiver(event); 118 | } 119 | } 120 | } 121 | 122 | @end -------------------------------------------------------------------------------- /AppleRemote/AppleRemote/AppleRemoteMapping.map: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/insidegui/AppleRemoteFramework/26a081d4f72ca27027682fac289333b7e794c34d/AppleRemote/AppleRemote/AppleRemoteMapping.map -------------------------------------------------------------------------------- /AppleRemote/AppleRemote/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | br.com.guilhermerambo.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | NSHumanReadableCopyright 24 | Copyright © 2015 Guilherme Rambo. All rights reserved. 25 | NSPrincipalClass 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /AppleRemote/AppleRemote/Internal Classes/HIDRemoteControlDevice.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * HIDRemoteControlDevice.h 3 | * RemoteControlWrapper 4 | * 5 | * Created by Martin Kahr on 11.03.06 under a MIT-style license. 6 | * Copyright (c) 2006 martinkahr.com. All rights reserved. 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a 9 | * copy of this software and associated documentation files (the "Software"), 10 | * to deal in the Software without restriction, including without limitation 11 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 | * and/or sell copies of the Software, and to permit persons to whom the 13 | * Software is furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included 16 | * in all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED ‚ÄúAS IS‚Äù, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | * THE SOFTWARE. 25 | * 26 | *****************************************************************************/ 27 | 28 | #import 29 | #import 30 | 31 | #import "RemoteControl.h" 32 | 33 | /* 34 | Base class for HID based remote control devices 35 | */ 36 | @interface HIDRemoteControlDevice : RemoteControl { 37 | IOHIDDeviceInterface** hidDeviceInterface; 38 | IOHIDQueueInterface** queue; 39 | NSMutableArray* allCookies; 40 | NSMutableDictionary* cookieToButtonMapping; 41 | CFRunLoopSourceRef eventSource; 42 | 43 | BOOL fixSecureEventInputBug; 44 | BOOL openInExclusiveMode; 45 | BOOL processesBacklog; 46 | 47 | int supportedButtonEvents; 48 | } 49 | 50 | // When your application needs to much time on the main thread when processing an event other events 51 | // may already be received which are put on a backlog. As soon as your main thread 52 | // has some spare time this backlog is processed and may flood your delegate with calls. 53 | // Backlog processing is turned off by default. 54 | - (BOOL) processesBacklog; 55 | - (void) setProcessesBacklog: (BOOL) value; 56 | 57 | // methods that should be overwritten by subclasses 58 | - (void) setCookieMappingInDictionary: (NSMutableDictionary*) cookieToButtonMapping; 59 | 60 | - (void) sendRemoteButtonEvent: (RemoteControlEventIdentifier) event pressedDown: (BOOL) pressedDown; 61 | 62 | + (BOOL) isRemoteAvailable; 63 | 64 | @end 65 | -------------------------------------------------------------------------------- /AppleRemote/AppleRemote/Internal Classes/HIDRemoteControlDevice.m: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * HIDRemoteControlDevice.m 3 | * RemoteControlWrapper 4 | * 5 | * Created by Martin Kahr on 11.03.06 under a MIT-style license. 6 | * Copyright (c) 2006 martinkahr.com. All rights reserved. 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a 9 | * copy of this software and associated documentation files (the "Software"), 10 | * to deal in the Software without restriction, including without limitation 11 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 | * and/or sell copies of the Software, and to permit persons to whom the 13 | * Software is furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included 16 | * in all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | * THE SOFTWARE. 25 | * 26 | *****************************************************************************/ 27 | 28 | #import "HIDRemoteControlDevice.h" 29 | 30 | #import 31 | #import 32 | #import 33 | #import 34 | #import 35 | #import 36 | 37 | @interface HIDRemoteControlDevice (PrivateMethods) 38 | - (NSDictionary*) cookieToButtonMapping; 39 | - (IOHIDQueueInterface**) queue; 40 | - (IOHIDDeviceInterface**) hidDeviceInterface; 41 | - (void) handleEventWithCookieString: (NSString*) cookieString sumOfValues: (SInt32) sumOfValues; 42 | - (void) removeNotifcationObserver; 43 | - (void) remoteControlAvailable:(NSNotification *)notification; 44 | 45 | @end 46 | 47 | @interface HIDRemoteControlDevice (IOKitMethods) 48 | + (io_object_t) findRemoteDevice; 49 | - (IOHIDDeviceInterface**) createInterfaceForDevice: (io_object_t) hidDevice; 50 | - (BOOL) initializeCookies; 51 | - (BOOL) openDevice; 52 | @end 53 | 54 | @implementation HIDRemoteControlDevice 55 | 56 | + (const char*) remoteControlDeviceName { 57 | return ""; 58 | } 59 | 60 | + (BOOL) isRemoteAvailable { 61 | io_object_t hidDevice = [self findRemoteDevice]; 62 | if (hidDevice != 0) { 63 | IOObjectRelease(hidDevice); 64 | return YES; 65 | } else { 66 | return NO; 67 | } 68 | } 69 | 70 | - (id) initWithDelegate: (id) _remoteControlDelegate { 71 | if ([[self class] isRemoteAvailable] == NO) return nil; 72 | 73 | if ( self = [super initWithDelegate: _remoteControlDelegate] ) { 74 | openInExclusiveMode = YES; 75 | queue = NULL; 76 | hidDeviceInterface = NULL; 77 | cookieToButtonMapping = [[NSMutableDictionary alloc] init]; 78 | 79 | [self setCookieMappingInDictionary: cookieToButtonMapping]; 80 | 81 | NSEnumerator* enumerator = [cookieToButtonMapping objectEnumerator]; 82 | NSNumber* identifier; 83 | supportedButtonEvents = 0; 84 | while(identifier = [enumerator nextObject]) { 85 | supportedButtonEvents |= [identifier intValue]; 86 | } 87 | 88 | fixSecureEventInputBug = [[NSUserDefaults standardUserDefaults] boolForKey: @"remoteControlWrapperFixSecureEventInputBug"]; 89 | } 90 | 91 | return self; 92 | } 93 | 94 | - (void) dealloc { 95 | [self removeNotifcationObserver]; 96 | [self stopListening:self]; 97 | [cookieToButtonMapping release]; 98 | [super dealloc]; 99 | } 100 | 101 | - (void) sendRemoteButtonEvent: (RemoteControlEventIdentifier) event pressedDown: (BOOL) pressedDown { 102 | [delegate sendRemoteButtonEvent: event pressedDown: pressedDown remoteControl:self]; 103 | } 104 | 105 | - (void) setCookieMappingInDictionary: (NSMutableDictionary*) cookieToButtonMapping { 106 | } 107 | - (int) remoteIdSwitchCookie { 108 | return 0; 109 | } 110 | 111 | - (BOOL) sendsEventForButtonIdentifier: (RemoteControlEventIdentifier) identifier { 112 | return (supportedButtonEvents & identifier) == identifier; 113 | } 114 | 115 | - (BOOL) isListeningToRemote { 116 | return (hidDeviceInterface != NULL && allCookies != NULL && queue != NULL); 117 | } 118 | 119 | - (void) setListeningToRemote: (BOOL) value { 120 | if (value == NO) { 121 | [self stopListening:self]; 122 | } else { 123 | [self startListening:self]; 124 | } 125 | } 126 | 127 | - (BOOL) isOpenInExclusiveMode { 128 | return openInExclusiveMode; 129 | } 130 | - (void) setOpenInExclusiveMode: (BOOL) value { 131 | openInExclusiveMode = value; 132 | } 133 | 134 | - (BOOL) processesBacklog { 135 | return processesBacklog; 136 | } 137 | - (void) setProcessesBacklog: (BOOL) value { 138 | processesBacklog = value; 139 | } 140 | 141 | - (IBAction) startListening: (id) sender { 142 | if ([self isListeningToRemote]) return; 143 | 144 | // 4th July 2007 145 | // 146 | // A security update in february of 2007 introduced an odd behavior. 147 | // Whenever SecureEventInput is activated or deactivated the exclusive access 148 | // to the remote control device is lost. This leads to very strange behavior where 149 | // a press on the Menu button activates FrontRow while your app still gets the event. 150 | // A great number of people have complained about this. 151 | // 152 | // Enabling the SecureEventInput and keeping it enabled does the trick. 153 | // 154 | // I'm pretty sure this is a kind of bug at Apple and I'm in contact with the responsible 155 | // Apple Engineer. This solution is not a perfect one - I know. 156 | // One of the side effects is that applications that listen for special global keyboard shortcuts (like Quicksilver) 157 | // may get into problems as they no longer get the events. 158 | // As there is no official Apple Remote API from Apple I also failed to open a technical incident on this. 159 | // 160 | // Note that there is a corresponding DisableSecureEventInput in the stopListening method below. 161 | // 162 | if ([self isOpenInExclusiveMode] && fixSecureEventInputBug) EnableSecureEventInput(); 163 | 164 | [self removeNotifcationObserver]; 165 | 166 | io_object_t hidDevice = [[self class] findRemoteDevice]; 167 | if (hidDevice == 0) return; 168 | 169 | if ([self createInterfaceForDevice:hidDevice] == NULL) { 170 | goto error; 171 | } 172 | 173 | if ([self initializeCookies]==NO) { 174 | goto error; 175 | } 176 | 177 | if ([self openDevice]==NO) { 178 | goto error; 179 | } 180 | // be KVO friendly 181 | [self willChangeValueForKey:@"listeningToRemote"]; 182 | [self didChangeValueForKey:@"listeningToRemote"]; 183 | goto cleanup; 184 | 185 | error: 186 | [self stopListening:self]; 187 | DisableSecureEventInput(); 188 | 189 | cleanup: 190 | IOObjectRelease(hidDevice); 191 | } 192 | 193 | - (IBAction) stopListening: (id) sender { 194 | if ([self isListeningToRemote]==NO) return; 195 | 196 | BOOL sendNotification = NO; 197 | 198 | if (eventSource != NULL) { 199 | CFRunLoopRemoveSource(CFRunLoopGetCurrent(), eventSource, kCFRunLoopDefaultMode); 200 | CFRelease(eventSource); 201 | eventSource = NULL; 202 | } 203 | if (queue != NULL) { 204 | (*queue)->stop(queue); 205 | 206 | //dispose of queue 207 | (*queue)->dispose(queue); 208 | 209 | //release the queue we allocated 210 | (*queue)->Release(queue); 211 | 212 | queue = NULL; 213 | 214 | sendNotification = YES; 215 | } 216 | 217 | if (allCookies != nil) { 218 | [allCookies autorelease]; 219 | allCookies = nil; 220 | } 221 | 222 | if (hidDeviceInterface != NULL) { 223 | //close the device 224 | (*hidDeviceInterface)->close(hidDeviceInterface); 225 | 226 | //release the interface 227 | (*hidDeviceInterface)->Release(hidDeviceInterface); 228 | 229 | hidDeviceInterface = NULL; 230 | } 231 | 232 | if ([self isOpenInExclusiveMode] && fixSecureEventInputBug) DisableSecureEventInput(); 233 | 234 | if ([self isOpenInExclusiveMode] && sendNotification) { 235 | [[self class] sendFinishedNotifcationForAppIdentifier: nil]; 236 | } 237 | // be KVO friendly 238 | [self willChangeValueForKey:@"listeningToRemote"]; 239 | [self didChangeValueForKey:@"listeningToRemote"]; 240 | } 241 | 242 | @end 243 | 244 | @implementation HIDRemoteControlDevice (PrivateMethods) 245 | 246 | - (IOHIDQueueInterface**) queue { 247 | return queue; 248 | } 249 | 250 | - (IOHIDDeviceInterface**) hidDeviceInterface { 251 | return hidDeviceInterface; 252 | } 253 | 254 | 255 | - (NSDictionary*) cookieToButtonMapping { 256 | return cookieToButtonMapping; 257 | } 258 | 259 | - (NSString*) validCookieSubstring: (NSString*) cookieString { 260 | if (cookieString == nil || [cookieString length] == 0) return nil; 261 | NSEnumerator* keyEnum = [[self cookieToButtonMapping] keyEnumerator]; 262 | NSString* key; 263 | while(key = [keyEnum nextObject]) { 264 | NSRange range = [cookieString rangeOfString:key]; 265 | if (range.location == 0) return key; 266 | } 267 | return nil; 268 | } 269 | 270 | - (void) handleEventWithCookieString: (NSString*) cookieString sumOfValues: (SInt32) sumOfValues { 271 | if ([[NSProcessInfo processInfo].environment.allKeys containsObject:@"DebugInfraRedCookies"]) { 272 | NSLog(@"[DebugInfraRedCookies] %@ %d", cookieString, sumOfValues); 273 | } 274 | 275 | /* 276 | if (previousRemainingCookieString) { 277 | cookieString = [previousRemainingCookieString stringByAppendingString: cookieString]; 278 | NSLog(@"New cookie string is %@", cookieString); 279 | [previousRemainingCookieString release], previousRemainingCookieString=nil; 280 | }*/ 281 | if (cookieString == nil || [cookieString length] == 0) return; 282 | 283 | NSNumber* buttonId = [[self cookieToButtonMapping] objectForKey: cookieString]; 284 | if (buttonId != nil) { 285 | [self sendRemoteButtonEvent: [buttonId intValue] pressedDown: (sumOfValues>0)]; 286 | } else { 287 | // let's see if a number of events are stored in the cookie string. this does 288 | // happen when the main thread is too busy to handle all incoming events in time. 289 | NSString* subCookieString; 290 | NSString* lastSubCookieString=nil; 291 | while((subCookieString = [self validCookieSubstring: cookieString])) { 292 | cookieString = [cookieString substringFromIndex: [subCookieString length]]; 293 | lastSubCookieString = subCookieString; 294 | if (processesBacklog) [self handleEventWithCookieString: subCookieString sumOfValues:sumOfValues]; 295 | } 296 | if (processesBacklog == NO && lastSubCookieString != nil) { 297 | // process the last event of the backlog and assume that the button is not pressed down any longer. 298 | // The events in the backlog do not seem to be in order and therefore (in rare cases) the last event might be 299 | // a button pressed down event while in reality the user has released it. 300 | // NSLog(@"processing last event of backlog"); 301 | [self handleEventWithCookieString: lastSubCookieString sumOfValues:0]; 302 | } 303 | if ([cookieString length] > 0) { 304 | NSLog(@"Unknown button for cookiestring %@", cookieString); 305 | } 306 | } 307 | } 308 | 309 | - (void) removeNotifcationObserver { 310 | [[NSDistributedNotificationCenter defaultCenter] removeObserver:self name:FINISHED_USING_REMOTE_CONTROL_NOTIFICATION object:nil]; 311 | } 312 | 313 | - (void) remoteControlAvailable:(NSNotification *)notification { 314 | [self removeNotifcationObserver]; 315 | [self startListening: self]; 316 | } 317 | 318 | @end 319 | 320 | /* Callback method for the device queue 321 | Will be called for any event of any type (cookie) to which we subscribe 322 | */ 323 | static void QueueCallbackFunction(void* target, IOReturn result, void* refcon, void* sender) { 324 | if (target < 0) { 325 | NSLog(@"QueueCallbackFunction called with invalid target!"); 326 | return; 327 | } 328 | NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; 329 | 330 | HIDRemoteControlDevice* remote = (HIDRemoteControlDevice*)target; 331 | IOHIDEventStruct event; 332 | AbsoluteTime zeroTime = {0,0}; 333 | NSMutableString* cookieString = [NSMutableString string]; 334 | SInt32 sumOfValues = 0; 335 | while (result == kIOReturnSuccess) 336 | { 337 | result = (*[remote queue])->getNextEvent([remote queue], &event, zeroTime, 0); 338 | if ( result != kIOReturnSuccess ) 339 | continue; 340 | 341 | //printf("%d %d %d\n", event.elementCookie, event.value, event.longValue); 342 | 343 | if (((int)event.elementCookie)!=5) { 344 | sumOfValues+=event.value; 345 | [cookieString appendString:[NSString stringWithFormat:@"%d_", event.elementCookie]]; 346 | } 347 | } 348 | [remote handleEventWithCookieString: cookieString sumOfValues: sumOfValues]; 349 | 350 | [pool release]; 351 | } 352 | 353 | @implementation HIDRemoteControlDevice (IOKitMethods) 354 | 355 | - (IOHIDDeviceInterface**) createInterfaceForDevice: (io_object_t) hidDevice { 356 | io_name_t className; 357 | IOCFPlugInInterface** plugInInterface = NULL; 358 | HRESULT plugInResult = S_OK; 359 | SInt32 score = 0; 360 | IOReturn ioReturnValue = kIOReturnSuccess; 361 | 362 | hidDeviceInterface = NULL; 363 | 364 | ioReturnValue = IOObjectGetClass(hidDevice, className); 365 | 366 | if (ioReturnValue != kIOReturnSuccess) { 367 | NSLog(@"Error: Failed to get class name."); 368 | return NULL; 369 | } 370 | 371 | ioReturnValue = IOCreatePlugInInterfaceForService(hidDevice, 372 | kIOHIDDeviceUserClientTypeID, 373 | kIOCFPlugInInterfaceID, 374 | &plugInInterface, 375 | &score); 376 | if (ioReturnValue == kIOReturnSuccess) 377 | { 378 | //Call a method of the intermediate plug-in to create the device interface 379 | plugInResult = (*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID), (LPVOID) &hidDeviceInterface); 380 | 381 | if (plugInResult != S_OK) { 382 | NSLog(@"Error: Couldn't create HID class device interface"); 383 | } 384 | // Release 385 | if (plugInInterface) (*plugInInterface)->Release(plugInInterface); 386 | } 387 | return hidDeviceInterface; 388 | } 389 | 390 | - (BOOL) initializeCookies { 391 | IOHIDDeviceInterface122** handle = (IOHIDDeviceInterface122**)hidDeviceInterface; 392 | IOHIDElementCookie cookie; 393 | long usage; 394 | long usagePage; 395 | id object; 396 | NSArray* elements = nil; 397 | NSDictionary* element; 398 | IOReturn success; 399 | 400 | if (!handle || !(*handle)) return NO; 401 | 402 | // Copy all elements, since we're grabbing most of the elements 403 | // for this device anyway, and thus, it's faster to iterate them 404 | // ourselves. When grabbing only one or two elements, a matching 405 | // dictionary should be passed in here instead of NULL. 406 | success = (*handle)->copyMatchingElements(handle, NULL, (CFArrayRef*)&elements); 407 | 408 | if (success == kIOReturnSuccess) { 409 | 410 | [elements autorelease]; 411 | /* 412 | cookies = calloc(NUMBER_OF_APPLE_REMOTE_ACTIONS, sizeof(IOHIDElementCookie)); 413 | memset(cookies, 0, sizeof(IOHIDElementCookie) * NUMBER_OF_APPLE_REMOTE_ACTIONS); 414 | */ 415 | allCookies = [[NSMutableArray alloc] init]; 416 | 417 | 418 | for (element in elements) { 419 | //Get cookie 420 | object = [element valueForKey: (NSString*)CFSTR(kIOHIDElementCookieKey) ]; 421 | if (object == nil || ![object isKindOfClass:[NSNumber class]]) continue; 422 | if (object == 0 || CFGetTypeID(object) != CFNumberGetTypeID()) continue; 423 | cookie = (IOHIDElementCookie) [object longValue]; 424 | 425 | //Get usage 426 | object = [element valueForKey: (NSString*)CFSTR(kIOHIDElementUsageKey) ]; 427 | if (object == nil || ![object isKindOfClass:[NSNumber class]]) continue; 428 | usage = [object longValue]; 429 | 430 | //Get usage page 431 | object = [element valueForKey: (NSString*)CFSTR(kIOHIDElementUsagePageKey) ]; 432 | if (object == nil || ![object isKindOfClass:[NSNumber class]]) continue; 433 | usagePage = [object longValue]; 434 | 435 | [allCookies addObject: [NSNumber numberWithInt:(int)cookie]]; 436 | } 437 | } else { 438 | return NO; 439 | } 440 | 441 | return YES; 442 | } 443 | 444 | - (BOOL) openDevice { 445 | HRESULT result; 446 | 447 | IOHIDOptionsType openMode = kIOHIDOptionsTypeNone; 448 | if ([self isOpenInExclusiveMode]) openMode = kIOHIDOptionsTypeSeizeDevice; 449 | IOReturn ioReturnValue = (*hidDeviceInterface)->open(hidDeviceInterface, openMode); 450 | 451 | if (ioReturnValue == KERN_SUCCESS) { 452 | queue = (*hidDeviceInterface)->allocQueue(hidDeviceInterface); 453 | if (queue) { 454 | result = (*queue)->create(queue, 0, 12); //depth: maximum number of elements in queue before oldest elements in queue begin to be lost. 455 | 456 | IOHIDElementCookie cookie; 457 | NSEnumerator *allCookiesEnumerator = [allCookies objectEnumerator]; 458 | 459 | while ((cookie = (IOHIDElementCookie)[[allCookiesEnumerator nextObject] intValue])) { 460 | (*queue)->addElement(queue, cookie, 0); 461 | } 462 | 463 | // add callback for async events 464 | ioReturnValue = (*queue)->createAsyncEventSource(queue, &eventSource); 465 | if (ioReturnValue == KERN_SUCCESS) { 466 | ioReturnValue = (*queue)->setEventCallout(queue,QueueCallbackFunction, self, NULL); 467 | if (ioReturnValue == KERN_SUCCESS) { 468 | CFRunLoopAddSource(CFRunLoopGetCurrent(), eventSource, kCFRunLoopDefaultMode); 469 | 470 | //start data delivery to queue 471 | (*queue)->start(queue); 472 | return YES; 473 | } else { 474 | NSLog(@"Error when setting event callback"); 475 | } 476 | } else { 477 | NSLog(@"Error when creating async event source"); 478 | } 479 | } else { 480 | NSLog(@"Error when opening device"); 481 | } 482 | } else if (ioReturnValue == kIOReturnExclusiveAccess) { 483 | // the device is used exclusive by another application 484 | 485 | // 1. we register for the FINISHED_USING_REMOTE_CONTROL_NOTIFICATION notification 486 | [[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(remoteControlAvailable:) name:FINISHED_USING_REMOTE_CONTROL_NOTIFICATION object:nil]; 487 | 488 | // 2. send a distributed notification that we wanted to use the remote control 489 | [[self class] sendRequestForRemoteControlNotification]; 490 | } 491 | return NO; 492 | } 493 | 494 | + (io_object_t) findRemoteDevice { 495 | CFMutableDictionaryRef hidMatchDictionary = NULL; 496 | IOReturn ioReturnValue = kIOReturnSuccess; 497 | io_iterator_t hidObjectIterator = 0; 498 | io_object_t hidDevice = 0; 499 | 500 | // Set up a matching dictionary to search the I/O Registry by class 501 | // name for all HID class devices 502 | hidMatchDictionary = IOServiceMatching([self remoteControlDeviceName]); 503 | 504 | // Now search I/O Registry for matching devices. 505 | ioReturnValue = IOServiceGetMatchingServices(kIOMasterPortDefault, hidMatchDictionary, &hidObjectIterator); 506 | 507 | if ((ioReturnValue == kIOReturnSuccess) && (hidObjectIterator != 0)) { 508 | hidDevice = IOIteratorNext(hidObjectIterator); 509 | } 510 | 511 | // release the iterator 512 | IOObjectRelease(hidObjectIterator); 513 | 514 | return hidDevice; 515 | } 516 | 517 | @end 518 | 519 | -------------------------------------------------------------------------------- /AppleRemote/AppleRemote/Internal Classes/RemoteControl.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * RemoteControl.h 3 | * RemoteControlWrapper 4 | * 5 | * Created by Martin Kahr on 11.03.06 under a MIT-style license. 6 | * Copyright (c) 2006 martinkahr.com. All rights reserved. 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a 9 | * copy of this software and associated documentation files (the "Software"), 10 | * to deal in the Software without restriction, including without limitation 11 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 | * and/or sell copies of the Software, and to permit persons to whom the 13 | * Software is furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included 16 | * in all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | * THE SOFTWARE. 25 | * 26 | *****************************************************************************/ 27 | 28 | #import 29 | 30 | // notifaction names that are being used to signal that an application wants to 31 | // have access to the remote control device or if the application has finished 32 | // using the remote control device 33 | extern NSString* REQUEST_FOR_REMOTE_CONTROL_NOTIFCATION; 34 | extern NSString* FINISHED_USING_REMOTE_CONTROL_NOTIFICATION; 35 | 36 | // keys used in user objects for distributed notifications 37 | extern NSString* kRemoteControlDeviceName; 38 | extern NSString* kApplicationIdentifier; 39 | extern NSString* kTargetApplicationIdentifier; 40 | 41 | // we have a 6 bit offset to make a hold event out of a normal event 42 | #define EVENT_TO_HOLD_EVENT_OFFSET 6 43 | 44 | @class RemoteControl; 45 | 46 | typedef enum _RemoteControlEventIdentifier { 47 | // normal events 48 | kRemoteButtonPlus =1<<1, 49 | kRemoteButtonMinus =1<<2, 50 | kRemoteButtonMenu =1<<3, 51 | kRemoteButtonPlay =1<<4, 52 | kRemoteButtonRight =1<<5, 53 | kRemoteButtonLeft =1<<6, 54 | 55 | // hold events 56 | kRemoteButtonPlus_Hold =1<<7, 57 | kRemoteButtonMinus_Hold =1<<8, 58 | kRemoteButtonMenu_Hold =1<<9, 59 | kRemoteButtonPlay_Hold =1<<10, 60 | kRemoteButtonRight_Hold =1<<11, 61 | kRemoteButtonLeft_Hold =1<<12, 62 | 63 | // special events (not supported by all devices) 64 | kRemoteControl_Switched =1<<13, 65 | 66 | // new button 67 | kRemoteButtonEnter =1<<14, 68 | kRemoteButtonEnter_Hold =1<<15, 69 | } RemoteControlEventIdentifier; 70 | 71 | @interface NSObject(RemoteControlDelegate) 72 | 73 | - (void) sendRemoteButtonEvent: (RemoteControlEventIdentifier) event pressedDown: (BOOL) pressedDown remoteControl: (RemoteControl*) remoteControl; 74 | 75 | @end 76 | 77 | /* 78 | Base Interface for Remote Control devices 79 | */ 80 | @interface RemoteControl : NSObject { 81 | id delegate; 82 | } 83 | 84 | // returns nil if the remote control device is not available 85 | - (id) initWithDelegate: (id) remoteControlDelegate; 86 | 87 | - (void) setListeningToRemote: (BOOL) value; 88 | - (BOOL) isListeningToRemote; 89 | 90 | - (BOOL) isOpenInExclusiveMode; 91 | - (void) setOpenInExclusiveMode: (BOOL) value; 92 | 93 | - (IBAction) startListening: (id) sender; 94 | - (IBAction) stopListening: (id) sender; 95 | 96 | // is this remote control sending the given event? 97 | - (BOOL) sendsEventForButtonIdentifier: (RemoteControlEventIdentifier) identifier; 98 | 99 | // sending of notifications between applications 100 | + (void) sendFinishedNotifcationForAppIdentifier: (NSString*) identifier; 101 | + (void) sendRequestForRemoteControlNotification; 102 | 103 | // name of the device 104 | + (const char*) remoteControlDeviceName; 105 | 106 | @end 107 | -------------------------------------------------------------------------------- /AppleRemote/AppleRemote/Internal Classes/RemoteControl.m: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * RemoteControl.m 3 | * RemoteControlWrapper 4 | * 5 | * Created by Martin Kahr on 11.03.06 under a MIT-style license. 6 | * Copyright (c) 2006 martinkahr.com. All rights reserved. 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a 9 | * copy of this software and associated documentation files (the "Software"), 10 | * to deal in the Software without restriction, including without limitation 11 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 | * and/or sell copies of the Software, and to permit persons to whom the 13 | * Software is furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included 16 | * in all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | * THE SOFTWARE. 25 | * 26 | *****************************************************************************/ 27 | 28 | #import "RemoteControl.h" 29 | 30 | // notifaction names that are being used to signal that an application wants to 31 | // have access to the remote control device or if the application has finished 32 | // using the remote control device 33 | NSString* REQUEST_FOR_REMOTE_CONTROL_NOTIFCATION = @"mac.remotecontrols.RequestForRemoteControl"; 34 | NSString* FINISHED_USING_REMOTE_CONTROL_NOTIFICATION = @"mac.remotecontrols.FinishedUsingRemoteControl"; 35 | 36 | // keys used in user objects for distributed notifications 37 | NSString* kRemoteControlDeviceName = @"RemoteControlDeviceName"; 38 | NSString* kApplicationIdentifier = @"CFBundleIdentifier"; 39 | 40 | 41 | @implementation RemoteControl 42 | 43 | // returns nil if the remote control device is not available 44 | - (id) initWithDelegate: (id) _remoteControlDelegate { 45 | if (self = [super init]) { 46 | delegate = [_remoteControlDelegate retain]; 47 | } 48 | return self; 49 | } 50 | 51 | - (void) dealloc { 52 | [delegate release]; 53 | [super dealloc]; 54 | } 55 | 56 | - (void) setListeningToRemote: (BOOL) value { 57 | } 58 | - (BOOL) isListeningToRemote { 59 | return NO; 60 | } 61 | 62 | - (IBAction) startListening: (id) sender { 63 | } 64 | - (IBAction) stopListening: (id) sender { 65 | 66 | } 67 | 68 | - (BOOL) isOpenInExclusiveMode { 69 | return YES; 70 | } 71 | - (void) setOpenInExclusiveMode: (BOOL) value { 72 | } 73 | 74 | - (BOOL) sendsEventForButtonIdentifier: (RemoteControlEventIdentifier) identifier { 75 | return YES; 76 | } 77 | 78 | + (void) sendDistributedNotification: (NSString*) notificationName targetBundleIdentifier: (NSString*) targetIdentifier { 79 | NSDictionary* userInfo = [NSDictionary dictionaryWithObjectsAndKeys: [NSString stringWithCString:[self remoteControlDeviceName] encoding:NSASCIIStringEncoding], 80 | kRemoteControlDeviceName, [[NSBundle mainBundle] bundleIdentifier], kApplicationIdentifier, 81 | targetIdentifier, [[NSBundle mainBundle] bundleIdentifier], nil]; 82 | 83 | [[NSDistributedNotificationCenter defaultCenter] postNotificationName:notificationName 84 | object:nil 85 | userInfo:userInfo 86 | deliverImmediately:YES]; 87 | } 88 | 89 | + (void) sendFinishedNotifcationForAppIdentifier: (NSString*) identifier { 90 | [self sendDistributedNotification:FINISHED_USING_REMOTE_CONTROL_NOTIFICATION targetBundleIdentifier:identifier]; 91 | } 92 | + (void) sendRequestForRemoteControlNotification { 93 | [self sendDistributedNotification:REQUEST_FOR_REMOTE_CONTROL_NOTIFCATION targetBundleIdentifier:nil]; 94 | } 95 | 96 | + (const char*) remoteControlDeviceName { 97 | return NULL; 98 | } 99 | 100 | @end 101 | -------------------------------------------------------------------------------- /Demos/ObjC/Apple Remote Demo/Apple Remote Demo.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | DDB6D7811A6459CB003B6EEA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = DDB6D7801A6459CB003B6EEA /* AppDelegate.m */; }; 11 | DDB6D7831A6459CB003B6EEA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = DDB6D7821A6459CB003B6EEA /* main.m */; }; 12 | DDB6D7851A6459CB003B6EEA /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DDB6D7841A6459CB003B6EEA /* Images.xcassets */; }; 13 | DDB6D7881A6459CB003B6EEA /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = DDB6D7861A6459CB003B6EEA /* MainMenu.xib */; }; 14 | DDE507551A98E0B300AB5E8E /* AppleRemote.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DDE507541A98E0A600AB5E8E /* AppleRemote.framework */; }; 15 | DDE507571A98E0B600AB5E8E /* AppleRemote.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = DDE507541A98E0A600AB5E8E /* AppleRemote.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 16 | DDE507601A98E0DF00AB5E8E /* AppleRemoteSimulator.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DDE5075F1A98E0D100AB5E8E /* AppleRemoteSimulator.framework */; }; 17 | DDE507621A98E0E200AB5E8E /* AppleRemoteSimulator.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = DDE5075F1A98E0D100AB5E8E /* AppleRemoteSimulator.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 18 | /* End PBXBuildFile section */ 19 | 20 | /* Begin PBXContainerItemProxy section */ 21 | DDE507531A98E0A600AB5E8E /* PBXContainerItemProxy */ = { 22 | isa = PBXContainerItemProxy; 23 | containerPortal = DDE5074F1A98E0A500AB5E8E /* AppleRemote.xcodeproj */; 24 | proxyType = 2; 25 | remoteGlobalIDString = DDB6D7551A64599C003B6EEA; 26 | remoteInfo = AppleRemote; 27 | }; 28 | DDE507581A98E0B600AB5E8E /* PBXContainerItemProxy */ = { 29 | isa = PBXContainerItemProxy; 30 | containerPortal = DDE5074F1A98E0A500AB5E8E /* AppleRemote.xcodeproj */; 31 | proxyType = 1; 32 | remoteGlobalIDString = DDB6D7541A64599C003B6EEA; 33 | remoteInfo = AppleRemote; 34 | }; 35 | DDE5075E1A98E0D100AB5E8E /* PBXContainerItemProxy */ = { 36 | isa = PBXContainerItemProxy; 37 | containerPortal = DDE5075A1A98E0D100AB5E8E /* AppleRemoteSimulator.xcodeproj */; 38 | proxyType = 2; 39 | remoteGlobalIDString = DDDB44B11A98DEF90047F7B7; 40 | remoteInfo = AppleRemoteSimulator; 41 | }; 42 | DDE507631A98E0E200AB5E8E /* PBXContainerItemProxy */ = { 43 | isa = PBXContainerItemProxy; 44 | containerPortal = DDE5075A1A98E0D100AB5E8E /* AppleRemoteSimulator.xcodeproj */; 45 | proxyType = 1; 46 | remoteGlobalIDString = DDDB44B01A98DEF90047F7B7; 47 | remoteInfo = AppleRemoteSimulator; 48 | }; 49 | /* End PBXContainerItemProxy section */ 50 | 51 | /* Begin PBXCopyFilesBuildPhase section */ 52 | DDB6D7AA1A645A14003B6EEA /* Embed Frameworks */ = { 53 | isa = PBXCopyFilesBuildPhase; 54 | buildActionMask = 2147483647; 55 | dstPath = ""; 56 | dstSubfolderSpec = 10; 57 | files = ( 58 | DDE507621A98E0E200AB5E8E /* AppleRemoteSimulator.framework in Embed Frameworks */, 59 | DDE507571A98E0B600AB5E8E /* AppleRemote.framework in Embed Frameworks */, 60 | ); 61 | name = "Embed Frameworks"; 62 | runOnlyForDeploymentPostprocessing = 0; 63 | }; 64 | /* End PBXCopyFilesBuildPhase section */ 65 | 66 | /* Begin PBXFileReference section */ 67 | DDB6D77A1A6459CB003B6EEA /* Apple Remote Demo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Apple Remote Demo.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 68 | DDB6D77E1A6459CB003B6EEA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 69 | DDB6D77F1A6459CB003B6EEA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 70 | DDB6D7801A6459CB003B6EEA /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 71 | DDB6D7821A6459CB003B6EEA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 72 | DDB6D7841A6459CB003B6EEA /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 73 | DDB6D7871A6459CB003B6EEA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; 74 | DDE5074F1A98E0A500AB5E8E /* AppleRemote.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = AppleRemote.xcodeproj; path = ../../../AppleRemote/AppleRemote.xcodeproj; sourceTree = ""; }; 75 | DDE5075A1A98E0D100AB5E8E /* AppleRemoteSimulator.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = AppleRemoteSimulator.xcodeproj; path = ../../shared/AppleRemoteSimulator/AppleRemoteSimulator.xcodeproj; sourceTree = ""; }; 76 | /* End PBXFileReference section */ 77 | 78 | /* Begin PBXFrameworksBuildPhase section */ 79 | DDB6D7771A6459CB003B6EEA /* Frameworks */ = { 80 | isa = PBXFrameworksBuildPhase; 81 | buildActionMask = 2147483647; 82 | files = ( 83 | DDE507551A98E0B300AB5E8E /* AppleRemote.framework in Frameworks */, 84 | DDE507601A98E0DF00AB5E8E /* AppleRemoteSimulator.framework in Frameworks */, 85 | ); 86 | runOnlyForDeploymentPostprocessing = 0; 87 | }; 88 | /* End PBXFrameworksBuildPhase section */ 89 | 90 | /* Begin PBXGroup section */ 91 | DDB6D7711A6459CB003B6EEA = { 92 | isa = PBXGroup; 93 | children = ( 94 | DDE5075A1A98E0D100AB5E8E /* AppleRemoteSimulator.xcodeproj */, 95 | DDE5074F1A98E0A500AB5E8E /* AppleRemote.xcodeproj */, 96 | DDB6D77C1A6459CB003B6EEA /* Apple Remote Demo */, 97 | DDB6D77B1A6459CB003B6EEA /* Products */, 98 | ); 99 | sourceTree = ""; 100 | }; 101 | DDB6D77B1A6459CB003B6EEA /* Products */ = { 102 | isa = PBXGroup; 103 | children = ( 104 | DDB6D77A1A6459CB003B6EEA /* Apple Remote Demo.app */, 105 | ); 106 | name = Products; 107 | sourceTree = ""; 108 | }; 109 | DDB6D77C1A6459CB003B6EEA /* Apple Remote Demo */ = { 110 | isa = PBXGroup; 111 | children = ( 112 | DDB6D77F1A6459CB003B6EEA /* AppDelegate.h */, 113 | DDB6D7801A6459CB003B6EEA /* AppDelegate.m */, 114 | DDB6D7841A6459CB003B6EEA /* Images.xcassets */, 115 | DDB6D7861A6459CB003B6EEA /* MainMenu.xib */, 116 | DDB6D77D1A6459CB003B6EEA /* Supporting Files */, 117 | ); 118 | path = "Apple Remote Demo"; 119 | sourceTree = ""; 120 | }; 121 | DDB6D77D1A6459CB003B6EEA /* Supporting Files */ = { 122 | isa = PBXGroup; 123 | children = ( 124 | DDB6D77E1A6459CB003B6EEA /* Info.plist */, 125 | DDB6D7821A6459CB003B6EEA /* main.m */, 126 | ); 127 | name = "Supporting Files"; 128 | sourceTree = ""; 129 | }; 130 | DDE507501A98E0A500AB5E8E /* Products */ = { 131 | isa = PBXGroup; 132 | children = ( 133 | DDE507541A98E0A600AB5E8E /* AppleRemote.framework */, 134 | ); 135 | name = Products; 136 | sourceTree = ""; 137 | }; 138 | DDE5075B1A98E0D100AB5E8E /* Products */ = { 139 | isa = PBXGroup; 140 | children = ( 141 | DDE5075F1A98E0D100AB5E8E /* AppleRemoteSimulator.framework */, 142 | ); 143 | name = Products; 144 | sourceTree = ""; 145 | }; 146 | /* End PBXGroup section */ 147 | 148 | /* Begin PBXNativeTarget section */ 149 | DDB6D7791A6459CB003B6EEA /* Apple Remote Demo */ = { 150 | isa = PBXNativeTarget; 151 | buildConfigurationList = DDB6D7971A6459CB003B6EEA /* Build configuration list for PBXNativeTarget "Apple Remote Demo" */; 152 | buildPhases = ( 153 | DDB6D7761A6459CB003B6EEA /* Sources */, 154 | DDB6D7771A6459CB003B6EEA /* Frameworks */, 155 | DDB6D7781A6459CB003B6EEA /* Resources */, 156 | DDB6D7AA1A645A14003B6EEA /* Embed Frameworks */, 157 | ); 158 | buildRules = ( 159 | ); 160 | dependencies = ( 161 | DDE507591A98E0B600AB5E8E /* PBXTargetDependency */, 162 | DDE507641A98E0E200AB5E8E /* PBXTargetDependency */, 163 | ); 164 | name = "Apple Remote Demo"; 165 | productName = "Apple Remote Demo"; 166 | productReference = DDB6D77A1A6459CB003B6EEA /* Apple Remote Demo.app */; 167 | productType = "com.apple.product-type.application"; 168 | }; 169 | /* End PBXNativeTarget section */ 170 | 171 | /* Begin PBXProject section */ 172 | DDB6D7721A6459CB003B6EEA /* Project object */ = { 173 | isa = PBXProject; 174 | attributes = { 175 | LastUpgradeCheck = 0610; 176 | ORGANIZATIONNAME = "Guilherme Rambo"; 177 | TargetAttributes = { 178 | DDB6D7791A6459CB003B6EEA = { 179 | CreatedOnToolsVersion = 6.1.1; 180 | }; 181 | }; 182 | }; 183 | buildConfigurationList = DDB6D7751A6459CB003B6EEA /* Build configuration list for PBXProject "Apple Remote Demo" */; 184 | compatibilityVersion = "Xcode 3.2"; 185 | developmentRegion = English; 186 | hasScannedForEncodings = 0; 187 | knownRegions = ( 188 | en, 189 | Base, 190 | ); 191 | mainGroup = DDB6D7711A6459CB003B6EEA; 192 | productRefGroup = DDB6D77B1A6459CB003B6EEA /* Products */; 193 | projectDirPath = ""; 194 | projectReferences = ( 195 | { 196 | ProductGroup = DDE507501A98E0A500AB5E8E /* Products */; 197 | ProjectRef = DDE5074F1A98E0A500AB5E8E /* AppleRemote.xcodeproj */; 198 | }, 199 | { 200 | ProductGroup = DDE5075B1A98E0D100AB5E8E /* Products */; 201 | ProjectRef = DDE5075A1A98E0D100AB5E8E /* AppleRemoteSimulator.xcodeproj */; 202 | }, 203 | ); 204 | projectRoot = ""; 205 | targets = ( 206 | DDB6D7791A6459CB003B6EEA /* Apple Remote Demo */, 207 | ); 208 | }; 209 | /* End PBXProject section */ 210 | 211 | /* Begin PBXReferenceProxy section */ 212 | DDE507541A98E0A600AB5E8E /* AppleRemote.framework */ = { 213 | isa = PBXReferenceProxy; 214 | fileType = wrapper.framework; 215 | path = AppleRemote.framework; 216 | remoteRef = DDE507531A98E0A600AB5E8E /* PBXContainerItemProxy */; 217 | sourceTree = BUILT_PRODUCTS_DIR; 218 | }; 219 | DDE5075F1A98E0D100AB5E8E /* AppleRemoteSimulator.framework */ = { 220 | isa = PBXReferenceProxy; 221 | fileType = wrapper.framework; 222 | path = AppleRemoteSimulator.framework; 223 | remoteRef = DDE5075E1A98E0D100AB5E8E /* PBXContainerItemProxy */; 224 | sourceTree = BUILT_PRODUCTS_DIR; 225 | }; 226 | /* End PBXReferenceProxy section */ 227 | 228 | /* Begin PBXResourcesBuildPhase section */ 229 | DDB6D7781A6459CB003B6EEA /* Resources */ = { 230 | isa = PBXResourcesBuildPhase; 231 | buildActionMask = 2147483647; 232 | files = ( 233 | DDB6D7851A6459CB003B6EEA /* Images.xcassets in Resources */, 234 | DDB6D7881A6459CB003B6EEA /* MainMenu.xib in Resources */, 235 | ); 236 | runOnlyForDeploymentPostprocessing = 0; 237 | }; 238 | /* End PBXResourcesBuildPhase section */ 239 | 240 | /* Begin PBXSourcesBuildPhase section */ 241 | DDB6D7761A6459CB003B6EEA /* Sources */ = { 242 | isa = PBXSourcesBuildPhase; 243 | buildActionMask = 2147483647; 244 | files = ( 245 | DDB6D7831A6459CB003B6EEA /* main.m in Sources */, 246 | DDB6D7811A6459CB003B6EEA /* AppDelegate.m in Sources */, 247 | ); 248 | runOnlyForDeploymentPostprocessing = 0; 249 | }; 250 | /* End PBXSourcesBuildPhase section */ 251 | 252 | /* Begin PBXTargetDependency section */ 253 | DDE507591A98E0B600AB5E8E /* PBXTargetDependency */ = { 254 | isa = PBXTargetDependency; 255 | name = AppleRemote; 256 | targetProxy = DDE507581A98E0B600AB5E8E /* PBXContainerItemProxy */; 257 | }; 258 | DDE507641A98E0E200AB5E8E /* PBXTargetDependency */ = { 259 | isa = PBXTargetDependency; 260 | name = AppleRemoteSimulator; 261 | targetProxy = DDE507631A98E0E200AB5E8E /* PBXContainerItemProxy */; 262 | }; 263 | /* End PBXTargetDependency section */ 264 | 265 | /* Begin PBXVariantGroup section */ 266 | DDB6D7861A6459CB003B6EEA /* MainMenu.xib */ = { 267 | isa = PBXVariantGroup; 268 | children = ( 269 | DDB6D7871A6459CB003B6EEA /* Base */, 270 | ); 271 | name = MainMenu.xib; 272 | sourceTree = ""; 273 | }; 274 | /* End PBXVariantGroup section */ 275 | 276 | /* Begin XCBuildConfiguration section */ 277 | DDB6D7951A6459CB003B6EEA /* Debug */ = { 278 | isa = XCBuildConfiguration; 279 | buildSettings = { 280 | ALWAYS_SEARCH_USER_PATHS = NO; 281 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 282 | CLANG_CXX_LIBRARY = "libc++"; 283 | CLANG_ENABLE_MODULES = YES; 284 | CLANG_ENABLE_OBJC_ARC = YES; 285 | CLANG_WARN_BOOL_CONVERSION = YES; 286 | CLANG_WARN_CONSTANT_CONVERSION = YES; 287 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 288 | CLANG_WARN_EMPTY_BODY = YES; 289 | CLANG_WARN_ENUM_CONVERSION = YES; 290 | CLANG_WARN_INT_CONVERSION = YES; 291 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 292 | CLANG_WARN_UNREACHABLE_CODE = YES; 293 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 294 | CODE_SIGN_IDENTITY = "-"; 295 | COPY_PHASE_STRIP = NO; 296 | ENABLE_STRICT_OBJC_MSGSEND = YES; 297 | GCC_C_LANGUAGE_STANDARD = gnu99; 298 | GCC_DYNAMIC_NO_PIC = NO; 299 | GCC_OPTIMIZATION_LEVEL = 0; 300 | GCC_PREPROCESSOR_DEFINITIONS = ( 301 | "DEBUG=1", 302 | "$(inherited)", 303 | ); 304 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 305 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 306 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 307 | GCC_WARN_UNDECLARED_SELECTOR = YES; 308 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 309 | GCC_WARN_UNUSED_FUNCTION = YES; 310 | GCC_WARN_UNUSED_VARIABLE = YES; 311 | MACOSX_DEPLOYMENT_TARGET = 10.10; 312 | MTL_ENABLE_DEBUG_INFO = YES; 313 | ONLY_ACTIVE_ARCH = YES; 314 | SDKROOT = macosx; 315 | }; 316 | name = Debug; 317 | }; 318 | DDB6D7961A6459CB003B6EEA /* Release */ = { 319 | isa = XCBuildConfiguration; 320 | buildSettings = { 321 | ALWAYS_SEARCH_USER_PATHS = NO; 322 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 323 | CLANG_CXX_LIBRARY = "libc++"; 324 | CLANG_ENABLE_MODULES = YES; 325 | CLANG_ENABLE_OBJC_ARC = YES; 326 | CLANG_WARN_BOOL_CONVERSION = YES; 327 | CLANG_WARN_CONSTANT_CONVERSION = YES; 328 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 329 | CLANG_WARN_EMPTY_BODY = YES; 330 | CLANG_WARN_ENUM_CONVERSION = YES; 331 | CLANG_WARN_INT_CONVERSION = YES; 332 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 333 | CLANG_WARN_UNREACHABLE_CODE = YES; 334 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 335 | CODE_SIGN_IDENTITY = "-"; 336 | COPY_PHASE_STRIP = YES; 337 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 338 | ENABLE_NS_ASSERTIONS = NO; 339 | ENABLE_STRICT_OBJC_MSGSEND = YES; 340 | GCC_C_LANGUAGE_STANDARD = gnu99; 341 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 342 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 343 | GCC_WARN_UNDECLARED_SELECTOR = YES; 344 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 345 | GCC_WARN_UNUSED_FUNCTION = YES; 346 | GCC_WARN_UNUSED_VARIABLE = YES; 347 | MACOSX_DEPLOYMENT_TARGET = 10.10; 348 | MTL_ENABLE_DEBUG_INFO = NO; 349 | SDKROOT = macosx; 350 | }; 351 | name = Release; 352 | }; 353 | DDB6D7981A6459CB003B6EEA /* Debug */ = { 354 | isa = XCBuildConfiguration; 355 | buildSettings = { 356 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 357 | COMBINE_HIDPI_IMAGES = YES; 358 | INFOPLIST_FILE = "Apple Remote Demo/Info.plist"; 359 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 360 | PRODUCT_NAME = "$(TARGET_NAME)"; 361 | }; 362 | name = Debug; 363 | }; 364 | DDB6D7991A6459CB003B6EEA /* Release */ = { 365 | isa = XCBuildConfiguration; 366 | buildSettings = { 367 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 368 | COMBINE_HIDPI_IMAGES = YES; 369 | INFOPLIST_FILE = "Apple Remote Demo/Info.plist"; 370 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 371 | PRODUCT_NAME = "$(TARGET_NAME)"; 372 | }; 373 | name = Release; 374 | }; 375 | /* End XCBuildConfiguration section */ 376 | 377 | /* Begin XCConfigurationList section */ 378 | DDB6D7751A6459CB003B6EEA /* Build configuration list for PBXProject "Apple Remote Demo" */ = { 379 | isa = XCConfigurationList; 380 | buildConfigurations = ( 381 | DDB6D7951A6459CB003B6EEA /* Debug */, 382 | DDB6D7961A6459CB003B6EEA /* Release */, 383 | ); 384 | defaultConfigurationIsVisible = 0; 385 | defaultConfigurationName = Release; 386 | }; 387 | DDB6D7971A6459CB003B6EEA /* Build configuration list for PBXNativeTarget "Apple Remote Demo" */ = { 388 | isa = XCConfigurationList; 389 | buildConfigurations = ( 390 | DDB6D7981A6459CB003B6EEA /* Debug */, 391 | DDB6D7991A6459CB003B6EEA /* Release */, 392 | ); 393 | defaultConfigurationIsVisible = 0; 394 | defaultConfigurationName = Release; 395 | }; 396 | /* End XCConfigurationList section */ 397 | }; 398 | rootObject = DDB6D7721A6459CB003B6EEA /* Project object */; 399 | } 400 | -------------------------------------------------------------------------------- /Demos/ObjC/Apple Remote Demo/Apple Remote Demo/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // Apple Remote Demo 4 | // 5 | // Created by Guilherme Rambo on 12/01/15. 6 | // Copyright (c) 2015 Guilherme Rambo. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : NSObject 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /Demos/ObjC/Apple Remote Demo/Apple Remote Demo/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // Apple Remote Demo 4 | // 5 | // Created by Guilherme Rambo on 12/01/15. 6 | // Copyright (c) 2015 Guilherme Rambo. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @import AppleRemote; 12 | @import AppleRemoteSimulator; 13 | 14 | @interface AppDelegate () 15 | 16 | @property (weak) IBOutlet NSWindow *window; 17 | @property (strong) AppleRemote *remote; 18 | 19 | @property (readonly) RSAppleRemoteDeviceView *appleRemoteView; 20 | 21 | @end 22 | 23 | @implementation AppDelegate 24 | 25 | - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { 26 | // setup an AppleRemote 27 | self.remote = [AppleRemote remoteWithListeningMode:AppleRemoteListenWhenActiveApp]; 28 | 29 | __weak typeof(self) weakSelf = self; 30 | 31 | // check if remote is available 32 | self.appleRemoteView.remoteUnavailable = [AppleRemote isRemoteAvailable]; 33 | 34 | // set the block to be called when a button is pressed 35 | [self.remote setPressEventReceiver:^(RemoteControlEventIdentifier eventId) { 36 | [weakSelf.appleRemoteView displayEvent:eventId]; 37 | }]; 38 | 39 | // set the block to be called when a button is released 40 | [self.remote setReleaseEventReceiver:^(RemoteControlEventIdentifier eventId) { 41 | [weakSelf.appleRemoteView hideEvent:eventId]; 42 | }]; 43 | } 44 | 45 | - (RSAppleRemoteDeviceView *)appleRemoteView 46 | { 47 | return (RSAppleRemoteDeviceView *)self.window.contentView; 48 | } 49 | 50 | - (void)applicationWillTerminate:(NSNotification *)aNotification { 51 | // Insert code here to tear down your application 52 | } 53 | 54 | @end 55 | -------------------------------------------------------------------------------- /Demos/ObjC/Apple Remote Demo/Apple Remote Demo/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "size" : "16x16", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "size" : "16x16", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "size" : "32x32", 16 | "scale" : "1x" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "size" : "32x32", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "size" : "128x128", 26 | "scale" : "1x" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "size" : "128x128", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "size" : "256x256", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "size" : "256x256", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "size" : "512x512", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "size" : "512x512", 51 | "scale" : "2x" 52 | } 53 | ], 54 | "info" : { 55 | "version" : 1, 56 | "author" : "xcode" 57 | } 58 | } -------------------------------------------------------------------------------- /Demos/ObjC/Apple Remote Demo/Apple Remote Demo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | br.com.guilhermerambo.$(PRODUCT_NAME:rfc1034identifier) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSMinimumSystemVersion 26 | $(MACOSX_DEPLOYMENT_TARGET) 27 | NSHumanReadableCopyright 28 | Copyright © 2015 Guilherme Rambo. All rights reserved. 29 | NSMainNibFile 30 | MainMenu 31 | NSPrincipalClass 32 | NSApplication 33 | 34 | 35 | -------------------------------------------------------------------------------- /Demos/ObjC/Apple Remote Demo/Apple Remote Demo/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // Apple Remote Demo 4 | // 5 | // Created by Guilherme Rambo on 12/01/15. 6 | // Copyright (c) 2015 Guilherme Rambo. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | int main(int argc, const char * argv[]) { 12 | return NSApplicationMain(argc, argv); 13 | } 14 | -------------------------------------------------------------------------------- /Demos/ObjC/Apple Remote Demo/resources/AppleRemote.pcvd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/insidegui/AppleRemoteFramework/26a081d4f72ca27027682fac289333b7e794c34d/Demos/ObjC/Apple Remote Demo/resources/AppleRemote.pcvd -------------------------------------------------------------------------------- /Demos/ObjC/Apple Remote Demo/resources/AppleRemoteUnavailable.pcvd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/insidegui/AppleRemoteFramework/26a081d4f72ca27027682fac289333b7e794c34d/Demos/ObjC/Apple Remote Demo/resources/AppleRemoteUnavailable.pcvd -------------------------------------------------------------------------------- /Demos/Swift/Apple Remote Swift Demo/Apple Remote Swift Demo.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | DDE507741A98E1D500AB5E8E /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDE507731A98E1D500AB5E8E /* AppDelegate.swift */; }; 11 | DDE507761A98E1D500AB5E8E /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DDE507751A98E1D500AB5E8E /* Images.xcassets */; }; 12 | DDE507791A98E1D500AB5E8E /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = DDE507771A98E1D500AB5E8E /* MainMenu.xib */; }; 13 | DDE5079B1A98E20100AB5E8E /* AppleRemote.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DDE507991A98E1F700AB5E8E /* AppleRemote.framework */; }; 14 | DDE5079C1A98E20100AB5E8E /* AppleRemote.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = DDE507991A98E1F700AB5E8E /* AppleRemote.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 15 | DDE507A01A98E20600AB5E8E /* AppleRemoteSimulator.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DDE507931A98E1EE00AB5E8E /* AppleRemoteSimulator.framework */; }; 16 | DDE507A11A98E20600AB5E8E /* AppleRemoteSimulator.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = DDE507931A98E1EE00AB5E8E /* AppleRemoteSimulator.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 17 | /* End PBXBuildFile section */ 18 | 19 | /* Begin PBXContainerItemProxy section */ 20 | DDE507921A98E1EE00AB5E8E /* PBXContainerItemProxy */ = { 21 | isa = PBXContainerItemProxy; 22 | containerPortal = DDE5078E1A98E1EE00AB5E8E /* AppleRemoteSimulator.xcodeproj */; 23 | proxyType = 2; 24 | remoteGlobalIDString = DDDB44B11A98DEF90047F7B7; 25 | remoteInfo = AppleRemoteSimulator; 26 | }; 27 | DDE507981A98E1F700AB5E8E /* PBXContainerItemProxy */ = { 28 | isa = PBXContainerItemProxy; 29 | containerPortal = DDE507941A98E1F700AB5E8E /* AppleRemote.xcodeproj */; 30 | proxyType = 2; 31 | remoteGlobalIDString = DDB6D7551A64599C003B6EEA; 32 | remoteInfo = AppleRemote; 33 | }; 34 | DDE5079D1A98E20100AB5E8E /* PBXContainerItemProxy */ = { 35 | isa = PBXContainerItemProxy; 36 | containerPortal = DDE507941A98E1F700AB5E8E /* AppleRemote.xcodeproj */; 37 | proxyType = 1; 38 | remoteGlobalIDString = DDB6D7541A64599C003B6EEA; 39 | remoteInfo = AppleRemote; 40 | }; 41 | DDE507A21A98E20600AB5E8E /* PBXContainerItemProxy */ = { 42 | isa = PBXContainerItemProxy; 43 | containerPortal = DDE5078E1A98E1EE00AB5E8E /* AppleRemoteSimulator.xcodeproj */; 44 | proxyType = 1; 45 | remoteGlobalIDString = DDDB44B01A98DEF90047F7B7; 46 | remoteInfo = AppleRemoteSimulator; 47 | }; 48 | /* End PBXContainerItemProxy section */ 49 | 50 | /* Begin PBXCopyFilesBuildPhase section */ 51 | DDE5079F1A98E20100AB5E8E /* Embed Frameworks */ = { 52 | isa = PBXCopyFilesBuildPhase; 53 | buildActionMask = 2147483647; 54 | dstPath = ""; 55 | dstSubfolderSpec = 10; 56 | files = ( 57 | DDE507A11A98E20600AB5E8E /* AppleRemoteSimulator.framework in Embed Frameworks */, 58 | DDE5079C1A98E20100AB5E8E /* AppleRemote.framework in Embed Frameworks */, 59 | ); 60 | name = "Embed Frameworks"; 61 | runOnlyForDeploymentPostprocessing = 0; 62 | }; 63 | /* End PBXCopyFilesBuildPhase section */ 64 | 65 | /* Begin PBXFileReference section */ 66 | DDE5076E1A98E1D500AB5E8E /* Apple Remote Swift Demo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Apple Remote Swift Demo.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 67 | DDE507721A98E1D500AB5E8E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 68 | DDE507731A98E1D500AB5E8E /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 69 | DDE507751A98E1D500AB5E8E /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 70 | DDE507781A98E1D500AB5E8E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; 71 | DDE5078E1A98E1EE00AB5E8E /* AppleRemoteSimulator.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = AppleRemoteSimulator.xcodeproj; path = ../../shared/AppleRemoteSimulator/AppleRemoteSimulator.xcodeproj; sourceTree = ""; }; 72 | DDE507941A98E1F700AB5E8E /* AppleRemote.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = AppleRemote.xcodeproj; path = ../../../AppleRemote/AppleRemote.xcodeproj; sourceTree = ""; }; 73 | /* End PBXFileReference section */ 74 | 75 | /* Begin PBXFrameworksBuildPhase section */ 76 | DDE5076B1A98E1D500AB5E8E /* Frameworks */ = { 77 | isa = PBXFrameworksBuildPhase; 78 | buildActionMask = 2147483647; 79 | files = ( 80 | DDE507A01A98E20600AB5E8E /* AppleRemoteSimulator.framework in Frameworks */, 81 | DDE5079B1A98E20100AB5E8E /* AppleRemote.framework in Frameworks */, 82 | ); 83 | runOnlyForDeploymentPostprocessing = 0; 84 | }; 85 | /* End PBXFrameworksBuildPhase section */ 86 | 87 | /* Begin PBXGroup section */ 88 | DDE507651A98E1D500AB5E8E = { 89 | isa = PBXGroup; 90 | children = ( 91 | DDE507941A98E1F700AB5E8E /* AppleRemote.xcodeproj */, 92 | DDE5078E1A98E1EE00AB5E8E /* AppleRemoteSimulator.xcodeproj */, 93 | DDE507701A98E1D500AB5E8E /* Apple Remote Swift Demo */, 94 | DDE5076F1A98E1D500AB5E8E /* Products */, 95 | ); 96 | sourceTree = ""; 97 | }; 98 | DDE5076F1A98E1D500AB5E8E /* Products */ = { 99 | isa = PBXGroup; 100 | children = ( 101 | DDE5076E1A98E1D500AB5E8E /* Apple Remote Swift Demo.app */, 102 | ); 103 | name = Products; 104 | sourceTree = ""; 105 | }; 106 | DDE507701A98E1D500AB5E8E /* Apple Remote Swift Demo */ = { 107 | isa = PBXGroup; 108 | children = ( 109 | DDE507731A98E1D500AB5E8E /* AppDelegate.swift */, 110 | DDE507751A98E1D500AB5E8E /* Images.xcassets */, 111 | DDE507771A98E1D500AB5E8E /* MainMenu.xib */, 112 | DDE507711A98E1D500AB5E8E /* Supporting Files */, 113 | ); 114 | path = "Apple Remote Swift Demo"; 115 | sourceTree = ""; 116 | }; 117 | DDE507711A98E1D500AB5E8E /* Supporting Files */ = { 118 | isa = PBXGroup; 119 | children = ( 120 | DDE507721A98E1D500AB5E8E /* Info.plist */, 121 | ); 122 | name = "Supporting Files"; 123 | sourceTree = ""; 124 | }; 125 | DDE5078F1A98E1EE00AB5E8E /* Products */ = { 126 | isa = PBXGroup; 127 | children = ( 128 | DDE507931A98E1EE00AB5E8E /* AppleRemoteSimulator.framework */, 129 | ); 130 | name = Products; 131 | sourceTree = ""; 132 | }; 133 | DDE507951A98E1F700AB5E8E /* Products */ = { 134 | isa = PBXGroup; 135 | children = ( 136 | DDE507991A98E1F700AB5E8E /* AppleRemote.framework */, 137 | ); 138 | name = Products; 139 | sourceTree = ""; 140 | }; 141 | /* End PBXGroup section */ 142 | 143 | /* Begin PBXNativeTarget section */ 144 | DDE5076D1A98E1D500AB5E8E /* Apple Remote Swift Demo */ = { 145 | isa = PBXNativeTarget; 146 | buildConfigurationList = DDE507881A98E1D500AB5E8E /* Build configuration list for PBXNativeTarget "Apple Remote Swift Demo" */; 147 | buildPhases = ( 148 | DDE5076A1A98E1D500AB5E8E /* Sources */, 149 | DDE5076B1A98E1D500AB5E8E /* Frameworks */, 150 | DDE5076C1A98E1D500AB5E8E /* Resources */, 151 | DDE5079F1A98E20100AB5E8E /* Embed Frameworks */, 152 | ); 153 | buildRules = ( 154 | ); 155 | dependencies = ( 156 | DDE5079E1A98E20100AB5E8E /* PBXTargetDependency */, 157 | DDE507A31A98E20600AB5E8E /* PBXTargetDependency */, 158 | ); 159 | name = "Apple Remote Swift Demo"; 160 | productName = "Apple Remote Swift Demo"; 161 | productReference = DDE5076E1A98E1D500AB5E8E /* Apple Remote Swift Demo.app */; 162 | productType = "com.apple.product-type.application"; 163 | }; 164 | /* End PBXNativeTarget section */ 165 | 166 | /* Begin PBXProject section */ 167 | DDE507661A98E1D500AB5E8E /* Project object */ = { 168 | isa = PBXProject; 169 | attributes = { 170 | LastUpgradeCheck = 0610; 171 | ORGANIZATIONNAME = "Guilherme Rambo"; 172 | TargetAttributes = { 173 | DDE5076D1A98E1D500AB5E8E = { 174 | CreatedOnToolsVersion = 6.1.1; 175 | }; 176 | }; 177 | }; 178 | buildConfigurationList = DDE507691A98E1D500AB5E8E /* Build configuration list for PBXProject "Apple Remote Swift Demo" */; 179 | compatibilityVersion = "Xcode 3.2"; 180 | developmentRegion = English; 181 | hasScannedForEncodings = 0; 182 | knownRegions = ( 183 | en, 184 | Base, 185 | ); 186 | mainGroup = DDE507651A98E1D500AB5E8E; 187 | productRefGroup = DDE5076F1A98E1D500AB5E8E /* Products */; 188 | projectDirPath = ""; 189 | projectReferences = ( 190 | { 191 | ProductGroup = DDE507951A98E1F700AB5E8E /* Products */; 192 | ProjectRef = DDE507941A98E1F700AB5E8E /* AppleRemote.xcodeproj */; 193 | }, 194 | { 195 | ProductGroup = DDE5078F1A98E1EE00AB5E8E /* Products */; 196 | ProjectRef = DDE5078E1A98E1EE00AB5E8E /* AppleRemoteSimulator.xcodeproj */; 197 | }, 198 | ); 199 | projectRoot = ""; 200 | targets = ( 201 | DDE5076D1A98E1D500AB5E8E /* Apple Remote Swift Demo */, 202 | ); 203 | }; 204 | /* End PBXProject section */ 205 | 206 | /* Begin PBXReferenceProxy section */ 207 | DDE507931A98E1EE00AB5E8E /* AppleRemoteSimulator.framework */ = { 208 | isa = PBXReferenceProxy; 209 | fileType = wrapper.framework; 210 | path = AppleRemoteSimulator.framework; 211 | remoteRef = DDE507921A98E1EE00AB5E8E /* PBXContainerItemProxy */; 212 | sourceTree = BUILT_PRODUCTS_DIR; 213 | }; 214 | DDE507991A98E1F700AB5E8E /* AppleRemote.framework */ = { 215 | isa = PBXReferenceProxy; 216 | fileType = wrapper.framework; 217 | path = AppleRemote.framework; 218 | remoteRef = DDE507981A98E1F700AB5E8E /* PBXContainerItemProxy */; 219 | sourceTree = BUILT_PRODUCTS_DIR; 220 | }; 221 | /* End PBXReferenceProxy section */ 222 | 223 | /* Begin PBXResourcesBuildPhase section */ 224 | DDE5076C1A98E1D500AB5E8E /* Resources */ = { 225 | isa = PBXResourcesBuildPhase; 226 | buildActionMask = 2147483647; 227 | files = ( 228 | DDE507761A98E1D500AB5E8E /* Images.xcassets in Resources */, 229 | DDE507791A98E1D500AB5E8E /* MainMenu.xib in Resources */, 230 | ); 231 | runOnlyForDeploymentPostprocessing = 0; 232 | }; 233 | /* End PBXResourcesBuildPhase section */ 234 | 235 | /* Begin PBXSourcesBuildPhase section */ 236 | DDE5076A1A98E1D500AB5E8E /* Sources */ = { 237 | isa = PBXSourcesBuildPhase; 238 | buildActionMask = 2147483647; 239 | files = ( 240 | DDE507741A98E1D500AB5E8E /* AppDelegate.swift in Sources */, 241 | ); 242 | runOnlyForDeploymentPostprocessing = 0; 243 | }; 244 | /* End PBXSourcesBuildPhase section */ 245 | 246 | /* Begin PBXTargetDependency section */ 247 | DDE5079E1A98E20100AB5E8E /* PBXTargetDependency */ = { 248 | isa = PBXTargetDependency; 249 | name = AppleRemote; 250 | targetProxy = DDE5079D1A98E20100AB5E8E /* PBXContainerItemProxy */; 251 | }; 252 | DDE507A31A98E20600AB5E8E /* PBXTargetDependency */ = { 253 | isa = PBXTargetDependency; 254 | name = AppleRemoteSimulator; 255 | targetProxy = DDE507A21A98E20600AB5E8E /* PBXContainerItemProxy */; 256 | }; 257 | /* End PBXTargetDependency section */ 258 | 259 | /* Begin PBXVariantGroup section */ 260 | DDE507771A98E1D500AB5E8E /* MainMenu.xib */ = { 261 | isa = PBXVariantGroup; 262 | children = ( 263 | DDE507781A98E1D500AB5E8E /* Base */, 264 | ); 265 | name = MainMenu.xib; 266 | sourceTree = ""; 267 | }; 268 | /* End PBXVariantGroup section */ 269 | 270 | /* Begin XCBuildConfiguration section */ 271 | DDE507861A98E1D500AB5E8E /* Debug */ = { 272 | isa = XCBuildConfiguration; 273 | buildSettings = { 274 | ALWAYS_SEARCH_USER_PATHS = NO; 275 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 276 | CLANG_CXX_LIBRARY = "libc++"; 277 | CLANG_ENABLE_MODULES = YES; 278 | CLANG_ENABLE_OBJC_ARC = YES; 279 | CLANG_WARN_BOOL_CONVERSION = YES; 280 | CLANG_WARN_CONSTANT_CONVERSION = YES; 281 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 282 | CLANG_WARN_EMPTY_BODY = YES; 283 | CLANG_WARN_ENUM_CONVERSION = YES; 284 | CLANG_WARN_INT_CONVERSION = YES; 285 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 286 | CLANG_WARN_UNREACHABLE_CODE = YES; 287 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 288 | CODE_SIGN_IDENTITY = "-"; 289 | COPY_PHASE_STRIP = NO; 290 | ENABLE_STRICT_OBJC_MSGSEND = YES; 291 | GCC_C_LANGUAGE_STANDARD = gnu99; 292 | GCC_DYNAMIC_NO_PIC = NO; 293 | GCC_OPTIMIZATION_LEVEL = 0; 294 | GCC_PREPROCESSOR_DEFINITIONS = ( 295 | "DEBUG=1", 296 | "$(inherited)", 297 | ); 298 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 299 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 300 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 301 | GCC_WARN_UNDECLARED_SELECTOR = YES; 302 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 303 | GCC_WARN_UNUSED_FUNCTION = YES; 304 | GCC_WARN_UNUSED_VARIABLE = YES; 305 | MACOSX_DEPLOYMENT_TARGET = 10.10; 306 | MTL_ENABLE_DEBUG_INFO = YES; 307 | ONLY_ACTIVE_ARCH = YES; 308 | SDKROOT = macosx; 309 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 310 | }; 311 | name = Debug; 312 | }; 313 | DDE507871A98E1D500AB5E8E /* Release */ = { 314 | isa = XCBuildConfiguration; 315 | buildSettings = { 316 | ALWAYS_SEARCH_USER_PATHS = NO; 317 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 318 | CLANG_CXX_LIBRARY = "libc++"; 319 | CLANG_ENABLE_MODULES = YES; 320 | CLANG_ENABLE_OBJC_ARC = YES; 321 | CLANG_WARN_BOOL_CONVERSION = YES; 322 | CLANG_WARN_CONSTANT_CONVERSION = YES; 323 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 324 | CLANG_WARN_EMPTY_BODY = YES; 325 | CLANG_WARN_ENUM_CONVERSION = YES; 326 | CLANG_WARN_INT_CONVERSION = YES; 327 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 328 | CLANG_WARN_UNREACHABLE_CODE = YES; 329 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 330 | CODE_SIGN_IDENTITY = "-"; 331 | COPY_PHASE_STRIP = YES; 332 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 333 | ENABLE_NS_ASSERTIONS = NO; 334 | ENABLE_STRICT_OBJC_MSGSEND = YES; 335 | GCC_C_LANGUAGE_STANDARD = gnu99; 336 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 337 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 338 | GCC_WARN_UNDECLARED_SELECTOR = YES; 339 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 340 | GCC_WARN_UNUSED_FUNCTION = YES; 341 | GCC_WARN_UNUSED_VARIABLE = YES; 342 | MACOSX_DEPLOYMENT_TARGET = 10.10; 343 | MTL_ENABLE_DEBUG_INFO = NO; 344 | SDKROOT = macosx; 345 | }; 346 | name = Release; 347 | }; 348 | DDE507891A98E1D500AB5E8E /* Debug */ = { 349 | isa = XCBuildConfiguration; 350 | buildSettings = { 351 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 352 | COMBINE_HIDPI_IMAGES = YES; 353 | INFOPLIST_FILE = "Apple Remote Swift Demo/Info.plist"; 354 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 355 | PRODUCT_NAME = "$(TARGET_NAME)"; 356 | }; 357 | name = Debug; 358 | }; 359 | DDE5078A1A98E1D500AB5E8E /* Release */ = { 360 | isa = XCBuildConfiguration; 361 | buildSettings = { 362 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 363 | COMBINE_HIDPI_IMAGES = YES; 364 | INFOPLIST_FILE = "Apple Remote Swift Demo/Info.plist"; 365 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 366 | PRODUCT_NAME = "$(TARGET_NAME)"; 367 | }; 368 | name = Release; 369 | }; 370 | /* End XCBuildConfiguration section */ 371 | 372 | /* Begin XCConfigurationList section */ 373 | DDE507691A98E1D500AB5E8E /* Build configuration list for PBXProject "Apple Remote Swift Demo" */ = { 374 | isa = XCConfigurationList; 375 | buildConfigurations = ( 376 | DDE507861A98E1D500AB5E8E /* Debug */, 377 | DDE507871A98E1D500AB5E8E /* Release */, 378 | ); 379 | defaultConfigurationIsVisible = 0; 380 | defaultConfigurationName = Release; 381 | }; 382 | DDE507881A98E1D500AB5E8E /* Build configuration list for PBXNativeTarget "Apple Remote Swift Demo" */ = { 383 | isa = XCConfigurationList; 384 | buildConfigurations = ( 385 | DDE507891A98E1D500AB5E8E /* Debug */, 386 | DDE5078A1A98E1D500AB5E8E /* Release */, 387 | ); 388 | defaultConfigurationIsVisible = 0; 389 | defaultConfigurationName = Release; 390 | }; 391 | /* End XCConfigurationList section */ 392 | }; 393 | rootObject = DDE507661A98E1D500AB5E8E /* Project object */; 394 | } 395 | -------------------------------------------------------------------------------- /Demos/Swift/Apple Remote Swift Demo/Apple Remote Swift Demo/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Apple Remote Swift Demo 4 | // 5 | // Created by Guilherme Rambo on 21/02/15. 6 | // Copyright (c) 2015 Guilherme Rambo. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | import AppleRemoteSimulator 12 | import AppleRemote 13 | 14 | @NSApplicationMain 15 | class AppDelegate: NSObject, NSApplicationDelegate { 16 | 17 | @IBOutlet weak var window: NSWindow! 18 | var appleRemoteView: RSAppleRemoteDeviceView { 19 | return window.contentView as RSAppleRemoteDeviceView 20 | } 21 | 22 | let remote = AppleRemote(listeningMode: .ListenWhenActiveApp) 23 | 24 | func applicationDidFinishLaunching(aNotification: NSNotification) { 25 | appleRemoteView.remoteUnavailable = AppleRemote.isRemoteAvailable() 26 | 27 | remote.pressEventReceiver = {[unowned self] eventId in 28 | self.appleRemoteView.displayEvent(Int32(eventId.value)) 29 | } 30 | 31 | remote.releaseEventReceiver = {[unowned self] eventId in 32 | self.appleRemoteView.hideEvent(Int32(eventId.value)) 33 | } 34 | } 35 | 36 | 37 | } 38 | 39 | -------------------------------------------------------------------------------- /Demos/Swift/Apple Remote Swift Demo/Apple Remote Swift Demo/Base.lproj/MainMenu.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 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 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 536 | 537 | 538 | Default 539 | 540 | 541 | 542 | 543 | 544 | 545 | Left to Right 546 | 547 | 548 | 549 | 550 | 551 | 552 | Right to Left 553 | 554 | 555 | 556 | 557 | 558 | 559 | 560 | 561 | 562 | 563 | Default 564 | 565 | 566 | 567 | 568 | 569 | 570 | Left to Right 571 | 572 | 573 | 574 | 575 | 576 | 577 | Right to Left 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 | 667 | 668 | 669 | 670 | 671 | 672 | 673 | 674 | 675 | 676 | 677 | 678 | 679 | 680 | 681 | 682 | -------------------------------------------------------------------------------- /Demos/Swift/Apple Remote Swift Demo/Apple Remote Swift Demo/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "size" : "16x16", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "size" : "16x16", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "size" : "32x32", 16 | "scale" : "1x" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "size" : "32x32", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "size" : "128x128", 26 | "scale" : "1x" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "size" : "128x128", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "size" : "256x256", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "size" : "256x256", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "size" : "512x512", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "size" : "512x512", 51 | "scale" : "2x" 52 | } 53 | ], 54 | "info" : { 55 | "version" : 1, 56 | "author" : "xcode" 57 | } 58 | } -------------------------------------------------------------------------------- /Demos/Swift/Apple Remote Swift Demo/Apple Remote Swift Demo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | br.com.guilhermerambo.$(PRODUCT_NAME:rfc1034identifier) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSMinimumSystemVersion 26 | $(MACOSX_DEPLOYMENT_TARGET) 27 | NSHumanReadableCopyright 28 | Copyright © 2015 Guilherme Rambo. All rights reserved. 29 | NSMainNibFile 30 | MainMenu 31 | NSPrincipalClass 32 | NSApplication 33 | 34 | 35 | -------------------------------------------------------------------------------- /Demos/shared/AppleRemoteSimulator/AppleRemoteSimulator.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | DDDB44B71A98DEF90047F7B7 /* AppleRemoteSimulator.h in Headers */ = {isa = PBXBuildFile; fileRef = DDDB44B61A98DEF90047F7B7 /* AppleRemoteSimulator.h */; settings = {ATTRIBUTES = (Public, ); }; }; 11 | DDDB44D11A98DF180047F7B7 /* RSAppleRemoteDeviceView.h in Headers */ = {isa = PBXBuildFile; fileRef = DDDB44CD1A98DF180047F7B7 /* RSAppleRemoteDeviceView.h */; settings = {ATTRIBUTES = (Public, ); }; }; 12 | DDDB44D21A98DF180047F7B7 /* RSAppleRemoteDeviceView.m in Sources */ = {isa = PBXBuildFile; fileRef = DDDB44CE1A98DF180047F7B7 /* RSAppleRemoteDeviceView.m */; }; 13 | DDDB44D31A98DF180047F7B7 /* RSRemoteDeviceSimulatorWindow.h in Headers */ = {isa = PBXBuildFile; fileRef = DDDB44CF1A98DF180047F7B7 /* RSRemoteDeviceSimulatorWindow.h */; settings = {ATTRIBUTES = (Public, ); }; }; 14 | DDDB44D41A98DF180047F7B7 /* RSRemoteDeviceSimulatorWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = DDDB44D01A98DF180047F7B7 /* RSRemoteDeviceSimulatorWindow.m */; }; 15 | /* End PBXBuildFile section */ 16 | 17 | /* Begin PBXFileReference section */ 18 | DDDB44B11A98DEF90047F7B7 /* AppleRemoteSimulator.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = AppleRemoteSimulator.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 19 | DDDB44B51A98DEF90047F7B7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 20 | DDDB44B61A98DEF90047F7B7 /* AppleRemoteSimulator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppleRemoteSimulator.h; sourceTree = ""; }; 21 | DDDB44CD1A98DF180047F7B7 /* RSAppleRemoteDeviceView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RSAppleRemoteDeviceView.h; sourceTree = ""; }; 22 | DDDB44CE1A98DF180047F7B7 /* RSAppleRemoteDeviceView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RSAppleRemoteDeviceView.m; sourceTree = ""; }; 23 | DDDB44CF1A98DF180047F7B7 /* RSRemoteDeviceSimulatorWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RSRemoteDeviceSimulatorWindow.h; sourceTree = ""; }; 24 | DDDB44D01A98DF180047F7B7 /* RSRemoteDeviceSimulatorWindow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RSRemoteDeviceSimulatorWindow.m; sourceTree = ""; }; 25 | /* End PBXFileReference section */ 26 | 27 | /* Begin PBXFrameworksBuildPhase section */ 28 | DDDB44AD1A98DEF90047F7B7 /* Frameworks */ = { 29 | isa = PBXFrameworksBuildPhase; 30 | buildActionMask = 2147483647; 31 | files = ( 32 | ); 33 | runOnlyForDeploymentPostprocessing = 0; 34 | }; 35 | /* End PBXFrameworksBuildPhase section */ 36 | 37 | /* Begin PBXGroup section */ 38 | DDDB44A71A98DEF90047F7B7 = { 39 | isa = PBXGroup; 40 | children = ( 41 | DDDB44B31A98DEF90047F7B7 /* AppleRemoteSimulator */, 42 | DDDB44B21A98DEF90047F7B7 /* Products */, 43 | ); 44 | sourceTree = ""; 45 | }; 46 | DDDB44B21A98DEF90047F7B7 /* Products */ = { 47 | isa = PBXGroup; 48 | children = ( 49 | DDDB44B11A98DEF90047F7B7 /* AppleRemoteSimulator.framework */, 50 | ); 51 | name = Products; 52 | sourceTree = ""; 53 | }; 54 | DDDB44B31A98DEF90047F7B7 /* AppleRemoteSimulator */ = { 55 | isa = PBXGroup; 56 | children = ( 57 | DDDB44CD1A98DF180047F7B7 /* RSAppleRemoteDeviceView.h */, 58 | DDDB44CE1A98DF180047F7B7 /* RSAppleRemoteDeviceView.m */, 59 | DDDB44CF1A98DF180047F7B7 /* RSRemoteDeviceSimulatorWindow.h */, 60 | DDDB44D01A98DF180047F7B7 /* RSRemoteDeviceSimulatorWindow.m */, 61 | DDDB44B61A98DEF90047F7B7 /* AppleRemoteSimulator.h */, 62 | DDDB44B41A98DEF90047F7B7 /* Supporting Files */, 63 | ); 64 | path = AppleRemoteSimulator; 65 | sourceTree = ""; 66 | }; 67 | DDDB44B41A98DEF90047F7B7 /* Supporting Files */ = { 68 | isa = PBXGroup; 69 | children = ( 70 | DDDB44B51A98DEF90047F7B7 /* Info.plist */, 71 | ); 72 | name = "Supporting Files"; 73 | sourceTree = ""; 74 | }; 75 | /* End PBXGroup section */ 76 | 77 | /* Begin PBXHeadersBuildPhase section */ 78 | DDDB44AE1A98DEF90047F7B7 /* Headers */ = { 79 | isa = PBXHeadersBuildPhase; 80 | buildActionMask = 2147483647; 81 | files = ( 82 | DDDB44B71A98DEF90047F7B7 /* AppleRemoteSimulator.h in Headers */, 83 | DDDB44D31A98DF180047F7B7 /* RSRemoteDeviceSimulatorWindow.h in Headers */, 84 | DDDB44D11A98DF180047F7B7 /* RSAppleRemoteDeviceView.h in Headers */, 85 | ); 86 | runOnlyForDeploymentPostprocessing = 0; 87 | }; 88 | /* End PBXHeadersBuildPhase section */ 89 | 90 | /* Begin PBXNativeTarget section */ 91 | DDDB44B01A98DEF90047F7B7 /* AppleRemoteSimulator */ = { 92 | isa = PBXNativeTarget; 93 | buildConfigurationList = DDDB44C71A98DEF90047F7B7 /* Build configuration list for PBXNativeTarget "AppleRemoteSimulator" */; 94 | buildPhases = ( 95 | DDDB44AC1A98DEF90047F7B7 /* Sources */, 96 | DDDB44AD1A98DEF90047F7B7 /* Frameworks */, 97 | DDDB44AE1A98DEF90047F7B7 /* Headers */, 98 | DDDB44AF1A98DEF90047F7B7 /* Resources */, 99 | ); 100 | buildRules = ( 101 | ); 102 | dependencies = ( 103 | ); 104 | name = AppleRemoteSimulator; 105 | productName = AppleRemoteSimulator; 106 | productReference = DDDB44B11A98DEF90047F7B7 /* AppleRemoteSimulator.framework */; 107 | productType = "com.apple.product-type.framework"; 108 | }; 109 | /* End PBXNativeTarget section */ 110 | 111 | /* Begin PBXProject section */ 112 | DDDB44A81A98DEF90047F7B7 /* Project object */ = { 113 | isa = PBXProject; 114 | attributes = { 115 | LastUpgradeCheck = 0610; 116 | ORGANIZATIONNAME = "Guilherme Rambo"; 117 | TargetAttributes = { 118 | DDDB44B01A98DEF90047F7B7 = { 119 | CreatedOnToolsVersion = 6.1.1; 120 | }; 121 | }; 122 | }; 123 | buildConfigurationList = DDDB44AB1A98DEF90047F7B7 /* Build configuration list for PBXProject "AppleRemoteSimulator" */; 124 | compatibilityVersion = "Xcode 3.2"; 125 | developmentRegion = English; 126 | hasScannedForEncodings = 0; 127 | knownRegions = ( 128 | en, 129 | ); 130 | mainGroup = DDDB44A71A98DEF90047F7B7; 131 | productRefGroup = DDDB44B21A98DEF90047F7B7 /* Products */; 132 | projectDirPath = ""; 133 | projectRoot = ""; 134 | targets = ( 135 | DDDB44B01A98DEF90047F7B7 /* AppleRemoteSimulator */, 136 | ); 137 | }; 138 | /* End PBXProject section */ 139 | 140 | /* Begin PBXResourcesBuildPhase section */ 141 | DDDB44AF1A98DEF90047F7B7 /* Resources */ = { 142 | isa = PBXResourcesBuildPhase; 143 | buildActionMask = 2147483647; 144 | files = ( 145 | ); 146 | runOnlyForDeploymentPostprocessing = 0; 147 | }; 148 | /* End PBXResourcesBuildPhase section */ 149 | 150 | /* Begin PBXSourcesBuildPhase section */ 151 | DDDB44AC1A98DEF90047F7B7 /* Sources */ = { 152 | isa = PBXSourcesBuildPhase; 153 | buildActionMask = 2147483647; 154 | files = ( 155 | DDDB44D21A98DF180047F7B7 /* RSAppleRemoteDeviceView.m in Sources */, 156 | DDDB44D41A98DF180047F7B7 /* RSRemoteDeviceSimulatorWindow.m in Sources */, 157 | ); 158 | runOnlyForDeploymentPostprocessing = 0; 159 | }; 160 | /* End PBXSourcesBuildPhase section */ 161 | 162 | /* Begin XCBuildConfiguration section */ 163 | DDDB44C51A98DEF90047F7B7 /* Debug */ = { 164 | isa = XCBuildConfiguration; 165 | buildSettings = { 166 | ALWAYS_SEARCH_USER_PATHS = NO; 167 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 168 | CLANG_CXX_LIBRARY = "libc++"; 169 | CLANG_ENABLE_MODULES = YES; 170 | CLANG_ENABLE_OBJC_ARC = YES; 171 | CLANG_WARN_BOOL_CONVERSION = YES; 172 | CLANG_WARN_CONSTANT_CONVERSION = YES; 173 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 174 | CLANG_WARN_EMPTY_BODY = YES; 175 | CLANG_WARN_ENUM_CONVERSION = YES; 176 | CLANG_WARN_INT_CONVERSION = YES; 177 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 178 | CLANG_WARN_UNREACHABLE_CODE = YES; 179 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 180 | COPY_PHASE_STRIP = NO; 181 | CURRENT_PROJECT_VERSION = 1; 182 | ENABLE_STRICT_OBJC_MSGSEND = YES; 183 | GCC_C_LANGUAGE_STANDARD = gnu99; 184 | GCC_DYNAMIC_NO_PIC = NO; 185 | GCC_OPTIMIZATION_LEVEL = 0; 186 | GCC_PREPROCESSOR_DEFINITIONS = ( 187 | "DEBUG=1", 188 | "$(inherited)", 189 | ); 190 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 191 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 192 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 193 | GCC_WARN_UNDECLARED_SELECTOR = YES; 194 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 195 | GCC_WARN_UNUSED_FUNCTION = YES; 196 | GCC_WARN_UNUSED_VARIABLE = YES; 197 | MACOSX_DEPLOYMENT_TARGET = 10.10; 198 | MTL_ENABLE_DEBUG_INFO = YES; 199 | ONLY_ACTIVE_ARCH = YES; 200 | SDKROOT = macosx; 201 | VERSIONING_SYSTEM = "apple-generic"; 202 | VERSION_INFO_PREFIX = ""; 203 | }; 204 | name = Debug; 205 | }; 206 | DDDB44C61A98DEF90047F7B7 /* Release */ = { 207 | isa = XCBuildConfiguration; 208 | buildSettings = { 209 | ALWAYS_SEARCH_USER_PATHS = NO; 210 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 211 | CLANG_CXX_LIBRARY = "libc++"; 212 | CLANG_ENABLE_MODULES = YES; 213 | CLANG_ENABLE_OBJC_ARC = YES; 214 | CLANG_WARN_BOOL_CONVERSION = YES; 215 | CLANG_WARN_CONSTANT_CONVERSION = YES; 216 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 217 | CLANG_WARN_EMPTY_BODY = YES; 218 | CLANG_WARN_ENUM_CONVERSION = YES; 219 | CLANG_WARN_INT_CONVERSION = YES; 220 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 221 | CLANG_WARN_UNREACHABLE_CODE = YES; 222 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 223 | COPY_PHASE_STRIP = YES; 224 | CURRENT_PROJECT_VERSION = 1; 225 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 226 | ENABLE_NS_ASSERTIONS = NO; 227 | ENABLE_STRICT_OBJC_MSGSEND = YES; 228 | GCC_C_LANGUAGE_STANDARD = gnu99; 229 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 230 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 231 | GCC_WARN_UNDECLARED_SELECTOR = YES; 232 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 233 | GCC_WARN_UNUSED_FUNCTION = YES; 234 | GCC_WARN_UNUSED_VARIABLE = YES; 235 | MACOSX_DEPLOYMENT_TARGET = 10.10; 236 | MTL_ENABLE_DEBUG_INFO = NO; 237 | SDKROOT = macosx; 238 | VERSIONING_SYSTEM = "apple-generic"; 239 | VERSION_INFO_PREFIX = ""; 240 | }; 241 | name = Release; 242 | }; 243 | DDDB44C81A98DEF90047F7B7 /* Debug */ = { 244 | isa = XCBuildConfiguration; 245 | buildSettings = { 246 | COMBINE_HIDPI_IMAGES = YES; 247 | DEFINES_MODULE = YES; 248 | DYLIB_COMPATIBILITY_VERSION = 1; 249 | DYLIB_CURRENT_VERSION = 1; 250 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 251 | FRAMEWORK_VERSION = A; 252 | INFOPLIST_FILE = AppleRemoteSimulator/Info.plist; 253 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 254 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; 255 | PRODUCT_NAME = "$(TARGET_NAME)"; 256 | SKIP_INSTALL = YES; 257 | }; 258 | name = Debug; 259 | }; 260 | DDDB44C91A98DEF90047F7B7 /* Release */ = { 261 | isa = XCBuildConfiguration; 262 | buildSettings = { 263 | COMBINE_HIDPI_IMAGES = YES; 264 | DEFINES_MODULE = YES; 265 | DYLIB_COMPATIBILITY_VERSION = 1; 266 | DYLIB_CURRENT_VERSION = 1; 267 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 268 | FRAMEWORK_VERSION = A; 269 | INFOPLIST_FILE = AppleRemoteSimulator/Info.plist; 270 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 271 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; 272 | PRODUCT_NAME = "$(TARGET_NAME)"; 273 | SKIP_INSTALL = YES; 274 | }; 275 | name = Release; 276 | }; 277 | /* End XCBuildConfiguration section */ 278 | 279 | /* Begin XCConfigurationList section */ 280 | DDDB44AB1A98DEF90047F7B7 /* Build configuration list for PBXProject "AppleRemoteSimulator" */ = { 281 | isa = XCConfigurationList; 282 | buildConfigurations = ( 283 | DDDB44C51A98DEF90047F7B7 /* Debug */, 284 | DDDB44C61A98DEF90047F7B7 /* Release */, 285 | ); 286 | defaultConfigurationIsVisible = 0; 287 | defaultConfigurationName = Release; 288 | }; 289 | DDDB44C71A98DEF90047F7B7 /* Build configuration list for PBXNativeTarget "AppleRemoteSimulator" */ = { 290 | isa = XCConfigurationList; 291 | buildConfigurations = ( 292 | DDDB44C81A98DEF90047F7B7 /* Debug */, 293 | DDDB44C91A98DEF90047F7B7 /* Release */, 294 | ); 295 | defaultConfigurationIsVisible = 0; 296 | defaultConfigurationName = Release; 297 | }; 298 | /* End XCConfigurationList section */ 299 | }; 300 | rootObject = DDDB44A81A98DEF90047F7B7 /* Project object */; 301 | } 302 | -------------------------------------------------------------------------------- /Demos/shared/AppleRemoteSimulator/AppleRemoteSimulator/AppleRemoteSimulator.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppleRemoteSimulator.h 3 | // AppleRemoteSimulator 4 | // 5 | // Created by Guilherme Rambo on 21/02/15. 6 | // Copyright (c) 2015 Guilherme Rambo. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for AppleRemoteSimulator. 12 | FOUNDATION_EXPORT double AppleRemoteSimulatorVersionNumber; 13 | 14 | //! Project version string for AppleRemoteSimulator. 15 | FOUNDATION_EXPORT const unsigned char AppleRemoteSimulatorVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | #import 21 | #import -------------------------------------------------------------------------------- /Demos/shared/AppleRemoteSimulator/AppleRemoteSimulator/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | br.com.guilhermerambo.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | NSHumanReadableCopyright 24 | Copyright © 2015 Guilherme Rambo. All rights reserved. 25 | NSPrincipalClass 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Demos/shared/AppleRemoteSimulator/AppleRemoteSimulator/RSAppleRemoteDeviceView.h: -------------------------------------------------------------------------------- 1 | // 2 | // RSAppleRemoteDeviceView 3 | // 4 | // Created by Guilherme Rambo on 21/02/15. 5 | // Copyright (c) 2015 Guilherme Rambo. All rights reserved. 6 | // 7 | 8 | @import Cocoa; 9 | 10 | @interface RSAppleRemoteDeviceView : NSView 11 | 12 | - (void)displayEvent:(int)event; 13 | - (void)hideEvent:(int)event; 14 | 15 | @property (nonatomic, assign, getter=isRemoteUnavailable) BOOL remoteUnavailable; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Demos/shared/AppleRemoteSimulator/AppleRemoteSimulator/RSAppleRemoteDeviceView.m: -------------------------------------------------------------------------------- 1 | // 2 | // RSAppleRemoteDeviceView 3 | // 4 | // Created by Guilherme Rambo on 21/02/15. 5 | // Copyright (c) 2015 Guilherme Rambo. All rights reserved. 6 | // 7 | 8 | #import "RSAppleRemoteDeviceView.h" 9 | 10 | typedef enum _RemoteControlEventIdentifier { 11 | // normal events 12 | kRemoteButtonPlus =1<<1, 13 | kRemoteButtonMinus =1<<2, 14 | kRemoteButtonMenu =1<<3, 15 | kRemoteButtonPlay =1<<4, 16 | kRemoteButtonRight =1<<5, 17 | kRemoteButtonLeft =1<<6, 18 | 19 | // hold events 20 | kRemoteButtonPlus_Hold =1<<7, 21 | kRemoteButtonMinus_Hold =1<<8, 22 | kRemoteButtonMenu_Hold =1<<9, 23 | kRemoteButtonPlay_Hold =1<<10, 24 | kRemoteButtonRight_Hold =1<<11, 25 | kRemoteButtonLeft_Hold =1<<12, 26 | 27 | // special events (not supported by all devices) 28 | kRemoteControl_Switched =1<<13, 29 | 30 | // new button 31 | kRemoteButtonEnter =1<<14, 32 | kRemoteButtonEnter_Hold =1<<15, 33 | } RemoteControlEventIdentifier; 34 | 35 | @implementation RSAppleRemoteDeviceView 36 | { 37 | NSMutableArray *_events; 38 | } 39 | 40 | - (void)setRemoteUnavailable:(BOOL)remoteUnavailable 41 | { 42 | _remoteUnavailable = remoteUnavailable; 43 | 44 | [self setNeedsDisplay:YES]; 45 | } 46 | 47 | - (void)displayEvent:(int)event 48 | { 49 | if (!_events) _events = [NSMutableArray new]; 50 | 51 | NSNumber *theEvent = @(event); 52 | if ([_events containsObject:theEvent]) return; 53 | 54 | [_events addObject:theEvent]; 55 | 56 | if (event == kRemoteButtonPlay || 57 | event == kRemoteButtonPlay_Hold || 58 | event == kRemoteButtonMenu || 59 | event == kRemoteButtonMenu_Hold || 60 | event == kRemoteButtonEnter || 61 | event == kRemoteButtonEnter_Hold) { 62 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ 63 | [self hideEvent:event]; 64 | }); 65 | } 66 | 67 | [self setNeedsDisplay:YES]; 68 | } 69 | 70 | - (void)hideEvent:(int)event 71 | { 72 | NSNumber *theEvent = @(event); 73 | if (![_events containsObject:theEvent]) return; 74 | 75 | [_events removeObject:theEvent]; 76 | 77 | [self setNeedsDisplay:YES]; 78 | } 79 | 80 | - (CGPoint)volumeUpPoint 81 | { 82 | return CGPointMake(57, 582); 83 | } 84 | 85 | - (CGPoint)volumeDownPoint 86 | { 87 | return CGPointMake(57, 468); 88 | } 89 | 90 | - (CGPoint)backwardPoint 91 | { 92 | return CGPointMake(1, 525); 93 | } 94 | 95 | - (CGPoint)forwardPoint 96 | { 97 | return CGPointMake(114, 525); 98 | } 99 | 100 | - (CGPoint)enterPoint 101 | { 102 | return CGPointMake(58, 522); 103 | } 104 | 105 | - (CGPoint)menuPoint 106 | { 107 | return CGPointMake(12, 393); 108 | } 109 | 110 | - (CGPoint)playPoint 111 | { 112 | return CGPointMake(102, 393); 113 | } 114 | 115 | - (void)drawPressedIndicatorAtPoint:(NSPoint)point 116 | { 117 | if ((point.x == [self menuPoint].x && point.y == [self menuPoint].y) || 118 | (point.x == [self playPoint].x && point.y == [self playPoint].y)) { 119 | [[NSGraphicsContext currentContext] setCompositingOperation:NSCompositePlusLighter]; 120 | } 121 | 122 | CGFloat pressedIndicatorSize = 60.0; 123 | CGFloat pressedIndicatorRadius = pressedIndicatorSize/2; 124 | 125 | //// Color Declarations 126 | NSColor* pressedGradientColor = [NSColor colorWithCalibratedRed: 0 green: 0.449 blue: 1 alpha: 0.9]; 127 | NSColor* pressedGradientColor2 = [NSColor colorWithCalibratedRed: 0 green: 0.539 blue: 1 alpha: 0]; 128 | 129 | //// Gradient Declarations 130 | NSGradient* pressedGradient = [[NSGradient alloc] initWithStartingColor: pressedGradientColor endingColor: pressedGradientColor2]; 131 | 132 | //// pressedShape Drawing 133 | NSBezierPath* pressedShapePath = [NSBezierPath bezierPathWithOvalInRect: NSMakeRect(point.x, point.y, pressedIndicatorSize, pressedIndicatorSize)]; 134 | [NSGraphicsContext saveGraphicsState]; 135 | [pressedShapePath addClip]; 136 | [pressedGradient drawFromCenter: NSMakePoint(pressedIndicatorRadius+point.x, pressedIndicatorRadius+point.y) radius: 5 137 | toCenter: NSMakePoint(pressedIndicatorRadius+point.x, pressedIndicatorRadius+point.y) radius: 27 138 | options: NSGradientDrawsBeforeStartingLocation | NSGradientDrawsAfterEndingLocation]; 139 | [NSGraphicsContext restoreGraphicsState]; 140 | } 141 | 142 | - (void)drawRect:(NSRect)dirtyRect { 143 | //// Color Declarations 144 | NSColor* bezelColor1 = [NSColor colorWithCalibratedRed: 0.811 green: 0.816 blue: 0.826 alpha: 1]; 145 | NSColor* bezelColor2 = [NSColor colorWithCalibratedRed: 0.864 green: 0.868 blue: 0.878 alpha: 1]; 146 | NSColor* bezelColor3 = [NSColor colorWithCalibratedRed: 0.479 green: 0.483 blue: 0.501 alpha: 1]; 147 | NSColor* bezelColor4 = [NSColor colorWithCalibratedRed: 0.687 green: 0.691 blue: 0.71 alpha: 1]; 148 | NSColor* bezelColor5 = [NSColor colorWithCalibratedRed: 0.854 green: 0.859 blue: 0.869 alpha: 1]; 149 | NSColor* buttonColor1 = [NSColor colorWithCalibratedRed: 0.109 green: 0.111 blue: 0.121 alpha: 1]; 150 | NSColor* buttonColor2 = [NSColor colorWithCalibratedRed: 0.022 green: 0.022 blue: 0.023 alpha: 1]; 151 | NSColor* enterButtonGradientColor = [NSColor colorWithCalibratedRed: 0.534 green: 0.537 blue: 0.556 alpha: 1]; 152 | NSColor* enterButtonGradientColor2 = [NSColor colorWithCalibratedRed: 0.84 green: 0.844 blue: 0.854 alpha: 1]; 153 | 154 | //// Gradient Declarations 155 | NSGradient* bezelGradient = [[NSGradient alloc] initWithColorsAndLocations: 156 | bezelColor1, 0.0, 157 | [NSColor colorWithCalibratedRed: 0.833 green: 0.837 blue: 0.847 alpha: 1], 0.05, 158 | bezelColor5, 0.19, 159 | bezelColor2, 0.37, 160 | [NSColor colorWithCalibratedRed: 0.775 green: 0.779 blue: 0.794 alpha: 1], 0.60, 161 | bezelColor4, 0.73, 162 | bezelColor3, 1.0, nil]; 163 | NSGradient* buttonGradient = [[NSGradient alloc] initWithStartingColor: buttonColor1 endingColor: buttonColor2]; 164 | NSGradient* enterButtonGradient = [[NSGradient alloc] initWithStartingColor: enterButtonGradientColor endingColor: enterButtonGradientColor2]; 165 | 166 | //// Shadow Declarations 167 | NSShadow* enterButtonInnerShadow = [[NSShadow alloc] init]; 168 | [enterButtonInnerShadow setShadowColor: [[NSColor blackColor] colorWithAlphaComponent: 0.3]]; 169 | [enterButtonInnerShadow setShadowOffset: NSMakeSize(3.1, 1.1)]; 170 | [enterButtonInnerShadow setShadowBlurRadius: 9]; 171 | 172 | //// Abstracted Attributes 173 | NSString* menuButtonTextContent = @"MENU"; 174 | 175 | 176 | //// appleRemoteBezel Drawing 177 | NSBezierPath* appleRemoteBezelPath = [NSBezierPath bezierPathWithRoundedRect: NSMakeRect(1, -1, 174, 701) xRadius: 23 yRadius: 23]; 178 | [bezelGradient drawInBezierPath: appleRemoteBezelPath angle: 0]; 179 | 180 | 181 | //// directionals Drawing 182 | NSBezierPath* directionalsPath = [NSBezierPath bezierPathWithOvalInRect: NSMakeRect(10, 477, 155, 155)]; 183 | [buttonGradient drawInBezierPath: directionalsPath angle: 0]; 184 | 185 | 186 | //// enterButton Drawing 187 | NSBezierPath* enterButtonPath = [NSBezierPath bezierPathWithOvalInRect: NSMakeRect(51, 517, 73, 73)]; 188 | [enterButtonGradient drawInBezierPath: enterButtonPath angle: -90]; 189 | 190 | ////// enterButton Inner Shadow 191 | NSRect enterButtonBorderRect = NSInsetRect([enterButtonPath bounds], -enterButtonInnerShadow.shadowBlurRadius, -enterButtonInnerShadow.shadowBlurRadius); 192 | enterButtonBorderRect = NSOffsetRect(enterButtonBorderRect, -enterButtonInnerShadow.shadowOffset.width, -enterButtonInnerShadow.shadowOffset.height); 193 | enterButtonBorderRect = NSInsetRect(NSUnionRect(enterButtonBorderRect, [enterButtonPath bounds]), -1, -1); 194 | 195 | NSBezierPath* enterButtonNegativePath = [NSBezierPath bezierPathWithRect: enterButtonBorderRect]; 196 | [enterButtonNegativePath appendBezierPath: enterButtonPath]; 197 | [enterButtonNegativePath setWindingRule: NSEvenOddWindingRule]; 198 | 199 | [NSGraphicsContext saveGraphicsState]; 200 | { 201 | NSShadow* enterButtonInnerShadowWithOffset = [enterButtonInnerShadow copy]; 202 | CGFloat xOffset = enterButtonInnerShadowWithOffset.shadowOffset.width + round(enterButtonBorderRect.size.width); 203 | CGFloat yOffset = enterButtonInnerShadowWithOffset.shadowOffset.height; 204 | enterButtonInnerShadowWithOffset.shadowOffset = NSMakeSize(xOffset + copysign(0.1, xOffset), yOffset + copysign(0.1, yOffset)); 205 | [enterButtonInnerShadowWithOffset set]; 206 | [[NSColor grayColor] setFill]; 207 | [enterButtonPath addClip]; 208 | NSAffineTransform* transform = [NSAffineTransform transform]; 209 | [transform translateXBy: -round(enterButtonBorderRect.size.width) yBy: 0]; 210 | [[transform transformBezierPath: enterButtonNegativePath] fill]; 211 | } 212 | [NSGraphicsContext restoreGraphicsState]; 213 | 214 | 215 | 216 | //// menuButton Drawing 217 | NSBezierPath* menuButtonPath = [NSBezierPath bezierPathWithOvalInRect: NSMakeRect(9.5, 390.5, 67, 67)]; 218 | [buttonGradient drawInBezierPath: menuButtonPath angle: -90]; 219 | 220 | 221 | //// playButton Drawing 222 | NSBezierPath* playButtonPath = [NSBezierPath bezierPathWithOvalInRect: NSMakeRect(99, 391, 67, 67)]; 223 | [buttonGradient drawInBezierPath: playButtonPath angle: -90]; 224 | 225 | 226 | //// menuButtonText Drawing 227 | NSRect menuButtonTextRect = NSMakeRect(23, 413, 40, 17); 228 | NSMutableParagraphStyle* menuButtonTextStyle = [[NSMutableParagraphStyle defaultParagraphStyle] mutableCopy]; 229 | [menuButtonTextStyle setAlignment: NSCenterTextAlignment]; 230 | 231 | NSDictionary* menuButtonTextFontAttributes = [NSDictionary dictionaryWithObjectsAndKeys: 232 | [NSFont boldSystemFontOfSize: 10.5], NSFontAttributeName, 233 | bezelColor2, NSForegroundColorAttributeName, 234 | menuButtonTextStyle, NSParagraphStyleAttributeName, nil]; 235 | 236 | [menuButtonTextContent drawInRect: NSOffsetRect(menuButtonTextRect, 0, 0) withAttributes: menuButtonTextFontAttributes]; 237 | 238 | 239 | //// playGlyph Drawing 240 | NSBezierPath* playGlyphPath = [NSBezierPath bezierPath]; 241 | [playGlyphPath moveToPoint: NSMakePoint(123.5, 429.5)]; 242 | [playGlyphPath lineToPoint: NSMakePoint(133.5, 424.5)]; 243 | [playGlyphPath lineToPoint: NSMakePoint(123.5, 419.5)]; 244 | [playGlyphPath lineToPoint: NSMakePoint(123.5, 429.5)]; 245 | [playGlyphPath closePath]; 246 | [bezelColor2 setFill]; 247 | [playGlyphPath fill]; 248 | 249 | 250 | //// pauseGlyph1 Drawing 251 | NSBezierPath* pauseGlyph1Path = [NSBezierPath bezierPathWithRect: NSMakeRect(136, 420, 2, 9)]; 252 | [bezelColor2 setFill]; 253 | [pauseGlyph1Path fill]; 254 | 255 | 256 | //// pauseGlyph2 Drawing 257 | NSBezierPath* pauseGlyph2Path = [NSBezierPath bezierPathWithRect: NSMakeRect(140, 420, 2, 9)]; 258 | [bezelColor2 setFill]; 259 | [pauseGlyph2Path fill]; 260 | 261 | if (self.isRemoteUnavailable) { 262 | return [self drawUnavailableOverlay]; 263 | } 264 | 265 | for (NSNumber *event in _events) { 266 | if (event.intValue == kRemoteButtonPlus || event.intValue == kRemoteButtonPlus_Hold) [self drawPressedIndicatorAtPoint:[self volumeUpPoint]]; 267 | if (event.intValue == kRemoteButtonMinus || event.intValue == kRemoteButtonMinus_Hold) [self drawPressedIndicatorAtPoint:[self volumeDownPoint]]; 268 | if (event.intValue == kRemoteButtonLeft_Hold) [self drawPressedIndicatorAtPoint:[self backwardPoint]]; 269 | if (event.intValue == kRemoteButtonRight_Hold) [self drawPressedIndicatorAtPoint:[self forwardPoint]]; 270 | if (event.intValue == kRemoteButtonEnter) [self drawPressedIndicatorAtPoint:[self enterPoint]]; 271 | if (event.intValue == kRemoteButtonMenu) [self drawPressedIndicatorAtPoint:[self menuPoint]]; 272 | if (event.intValue == kRemoteButtonPlay) [self drawPressedIndicatorAtPoint:[self playPoint]]; 273 | } 274 | } 275 | 276 | - (void)drawUnavailableOverlay 277 | { 278 | //// Color Declarations 279 | NSColor* unavailableOverlayColor = [NSColor colorWithCalibratedRed: 1 green: 1 blue: 1 alpha: 0.733]; 280 | NSColor* unavailableTextColor = [NSColor colorWithCalibratedRed: 0.886 green: 0 blue: 0 alpha: 1]; 281 | 282 | //// Abstracted Attributes 283 | NSString* unavailableTextContent = @"Infrared is not available"; 284 | 285 | 286 | //// unavailableOverlay Drawing 287 | NSBezierPath* unavailableOverlayPath = [NSBezierPath bezierPathWithRoundedRect: NSMakeRect(1, -1, 174, 701) xRadius: 23 yRadius: 23]; 288 | [unavailableOverlayColor setFill]; 289 | [unavailableOverlayPath fill]; 290 | 291 | 292 | //// unavailableText Drawing 293 | NSRect unavailableTextRect = NSMakeRect(18, 656, 140, 17); 294 | NSMutableParagraphStyle* unavailableTextStyle = [[NSMutableParagraphStyle defaultParagraphStyle] mutableCopy]; 295 | [unavailableTextStyle setAlignment: NSCenterTextAlignment]; 296 | 297 | NSDictionary* unavailableTextFontAttributes = [NSDictionary dictionaryWithObjectsAndKeys: 298 | [NSFont boldSystemFontOfSize: [NSFont smallSystemFontSize]], NSFontAttributeName, 299 | unavailableTextColor, NSForegroundColorAttributeName, 300 | unavailableTextStyle, NSParagraphStyleAttributeName, nil]; 301 | 302 | [unavailableTextContent drawInRect: NSOffsetRect(unavailableTextRect, 0, 0) withAttributes: unavailableTextFontAttributes]; 303 | } 304 | 305 | @end 306 | -------------------------------------------------------------------------------- /Demos/shared/AppleRemoteSimulator/AppleRemoteSimulator/RSRemoteDeviceSimulatorWindow.h: -------------------------------------------------------------------------------- 1 | // 2 | // RSRemoteDeviceSimulatorWindow 3 | // 4 | // Created by Guilherme Rambo on 21/02/15. 5 | // Copyright (c) 2015 Guilherme Rambo. All rights reserved. 6 | // 7 | 8 | @import Cocoa; 9 | 10 | @interface RSRemoteDeviceSimulatorWindow : NSWindow 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /Demos/shared/AppleRemoteSimulator/AppleRemoteSimulator/RSRemoteDeviceSimulatorWindow.m: -------------------------------------------------------------------------------- 1 | // 2 | // RSRemoteDeviceSimulatorWindow 3 | // 4 | // Created by Guilherme Rambo on 21/02/15. 5 | // Copyright (c) 2015 Guilherme Rambo. All rights reserved. 6 | // 7 | 8 | #import "RSRemoteDeviceSimulatorWindow.h" 9 | 10 | @implementation RSRemoteDeviceSimulatorWindow 11 | 12 | - (void)awakeFromNib 13 | { 14 | [super awakeFromNib]; 15 | 16 | [self setMovableByWindowBackground:YES]; 17 | [self center]; 18 | } 19 | 20 | - (instancetype)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)aStyle backing:(NSBackingStoreType)bufferingType defer:(BOOL)flag 21 | { 22 | if (!(self = [super initWithContentRect:contentRect styleMask:aStyle backing:bufferingType defer:flag])) return nil; 23 | 24 | self.opaque = NO; 25 | self.backgroundColor = [NSColor clearColor]; 26 | self.movableByWindowBackground = YES; 27 | 28 | return self; 29 | } 30 | 31 | - (void)makeKeyAndOrderFront:(id)sender 32 | { 33 | [self center]; 34 | [super makeKeyAndOrderFront:sender]; 35 | } 36 | 37 | - (BOOL)canBecomeKeyWindow 38 | { 39 | return YES; 40 | } 41 | 42 | - (BOOL)canBecomeMainWindow 43 | { 44 | return YES; 45 | } 46 | 47 | @end 48 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Guilherme Rambo 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Apple Remote Framework 2 | 3 | A framework to use the Apple Remote to control your apps. 4 | 5 | ## Documentation 6 | 7 | The functionality is wrapped in a single class: `AppleRemote`. Take a look at the header, it's pretty well documented. 8 | 9 | The sample app included shows a really good example of how It can be used, but the basic usage is as shown below: 10 | 11 | ### Objective-C 12 | 13 | ```objective-c 14 | // setup an AppleRemote 15 | self.remote = [AppleRemote remoteWithListeningMode:AppleRemoteListenWhenActiveApp]; 16 | 17 | // set the block to be called when a button is pressed 18 | [self.remote setPressEventReceiver:^(RemoteControlEventIdentifier eventId) { 19 | // do something with eventId, probably a switch :) 20 | }]; 21 | 22 | // set the block to be called when a button is released 23 | [self.remote setReleaseEventReceiver:^(RemoteControlEventIdentifier eventId) { 24 | // do something with eventId 25 | }]; 26 | ``` 27 | 28 | ### Swift 29 | 30 | ```swift 31 | // setup an AppleRemote 32 | let remote = AppleRemote(listeningMode: .ListenWhenActiveApp) 33 | 34 | // set the block to be called when a button is pressed 35 | remote.pressEventReceiver = { eventId in 36 | // do something with eventId, probably a switch :) 37 | } 38 | 39 | // set the block to be called when a button is released 40 | remote.releaseEventReceiver = { eventId in 41 | // do something with eventId 42 | } 43 | ``` 44 | 45 | ![demo app screenshot](https://raw.github.com/insidegui/AppleRemoteFramework/master/screenshot.png) 46 | 47 | #### Thanks 48 | 49 | This framework is based on classes created by **Martin Kahr**, thanks Martin for your great work. 50 | 51 | #### Contributing 52 | 53 | You can contribute with code, just send me a pull request, or open an issue for any bug/enhancement. Please try to code in a similar way to the code that's already been written. 54 | 55 | Disclaimer: sending a pull request does not mean I will accept It, if I don't accept your pull request It doesn't mean I don't love you ;) -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/insidegui/AppleRemoteFramework/26a081d4f72ca27027682fac289333b7e794c34d/screenshot.png --------------------------------------------------------------------------------