├── .gitignore ├── .idea ├── .name ├── BLEMingleiOS.iml ├── encodings.xml ├── misc.xml ├── modules.xml ├── scopes │ └── scope_settings.xml ├── vcs.xml └── xcode.xml ├── BLEMingleiOS.xcodeproj ├── project.pbxproj └── xcuserdata │ └── michaeloriley.xcuserdatad │ └── xcschemes │ └── BLEMingleiOS.xcscheme ├── BLEMingleiOS ├── AppDelegate.swift ├── BLECentralDelegate.swift ├── BLEMingle.swift ├── Base.lproj │ ├── LaunchScreen.xib │ └── Main.storyboard ├── Images.xcassets │ ├── AppIcon.appiconset │ │ ├── 120-1.png │ │ ├── 120.png │ │ ├── 180.png │ │ ├── 58.png │ │ ├── 80.png │ │ ├── 87.png │ │ └── Contents.json │ └── LaunchImage.launchimage │ │ └── Contents.json ├── Info.plist └── ViewController.swift ├── BLEMingleiOSTests ├── BLEMingleiOSTests.swift └── Info.plist └── readme.md /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.xcuserdatad 3 | *.xcworkspace 4 | -------------------------------------------------------------------------------- /.idea/.name: -------------------------------------------------------------------------------- 1 | BLEMingleiOS -------------------------------------------------------------------------------- /.idea/BLEMingleiOS.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | 10 | 11 | 12 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/scopes/scope_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/xcode.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /BLEMingleiOS.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 48; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | C6B5318859EA97BB636A8732 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6B533F81216A87853F21C19 /* ViewController.swift */; }; 11 | C6B5327D61B61344D39AD70A /* BLEMingle.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6B53290F4EE496024C9E6DC /* BLEMingle.swift */; }; 12 | C6B5378475849A5F25B4BCEE /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6B5365609B299B399A82E17 /* AppDelegate.swift */; }; 13 | C6B53998A54B598D73E39B10 /* BLECentralDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6B532DDF8E57F1D39796DBD /* BLECentralDelegate.swift */; }; 14 | C6B53A2DC8725D2896EE0E7A /* BLEMingle.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6B53290F4EE496024C9E6DC /* BLEMingle.swift */; }; 15 | C6B53BE00254A80475662DB5 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C6B53B146074C0922474E6DB /* Main.storyboard */; }; 16 | C6B53BF0410A2118C8757C79 /* BLECentralDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6B532DDF8E57F1D39796DBD /* BLECentralDelegate.swift */; }; 17 | C6B53EBBEEF22DD820FED288 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = C6B53BC2F791CF18B27CEC35 /* LaunchScreen.xib */; }; 18 | C6B53F1817DD2F23C25C7A1D /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C6B53F669DA11C1FAF4F7DE4 /* Images.xcassets */; }; 19 | /* End PBXBuildFile section */ 20 | 21 | /* Begin PBXContainerItemProxy section */ 22 | C6B533792402EEC578E6F23B /* PBXContainerItemProxy */ = { 23 | isa = PBXContainerItemProxy; 24 | containerPortal = C6B53155DE36BC07F1E0969F /* Project object */; 25 | proxyType = 1; 26 | remoteGlobalIDString = C6B53501502AC80DD49A29CC; 27 | remoteInfo = BLEMingleiOS; 28 | }; 29 | /* End PBXContainerItemProxy section */ 30 | 31 | /* Begin PBXFileReference section */ 32 | C6B531CF1BB813835FC07E49 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 33 | C6B53290F4EE496024C9E6DC /* BLEMingle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BLEMingle.swift; sourceTree = ""; }; 34 | C6B532DDF8E57F1D39796DBD /* BLECentralDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BLECentralDelegate.swift; sourceTree = ""; }; 35 | C6B533F81216A87853F21C19 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 36 | C6B535513310D10E6D1577F1 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 37 | C6B5365609B299B399A82E17 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 38 | C6B53B7526F2E72E0A84DC45 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.info; path = Info.plist; sourceTree = ""; }; 39 | C6B53C549156A54E0778B8BA /* BLEMingleiOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = BLEMingleiOS.app; sourceTree = BUILT_PRODUCTS_DIR; }; 40 | C6B53F669DA11C1FAF4F7DE4 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 41 | /* End PBXFileReference section */ 42 | 43 | /* Begin PBXFrameworksBuildPhase section */ 44 | C6B5349EB3D7A54922266B9C /* Frameworks */ = { 45 | isa = PBXFrameworksBuildPhase; 46 | buildActionMask = 2147483647; 47 | files = ( 48 | ); 49 | runOnlyForDeploymentPostprocessing = 0; 50 | }; 51 | C6B53724F3F9FA07BF34FD28 /* Frameworks */ = { 52 | isa = PBXFrameworksBuildPhase; 53 | buildActionMask = 2147483647; 54 | files = ( 55 | ); 56 | runOnlyForDeploymentPostprocessing = 0; 57 | }; 58 | /* End PBXFrameworksBuildPhase section */ 59 | 60 | /* Begin PBXGroup section */ 61 | C6B531652B6EF3ADD201724D = { 62 | isa = PBXGroup; 63 | children = ( 64 | C6B53F873D693F3D16B75CB3 /* Products */, 65 | C6B53C2544968C1FE8A15F23 /* BLEMingleiOS */, 66 | ); 67 | sourceTree = ""; 68 | }; 69 | C6B535E2003C2C5CFEAFF613 /* Supporting Files */ = { 70 | isa = PBXGroup; 71 | children = ( 72 | C6B53B7526F2E72E0A84DC45 /* Info.plist */, 73 | ); 74 | name = "Supporting Files"; 75 | sourceTree = ""; 76 | }; 77 | C6B53C2544968C1FE8A15F23 /* BLEMingleiOS */ = { 78 | isa = PBXGroup; 79 | children = ( 80 | C6B535E2003C2C5CFEAFF613 /* Supporting Files */, 81 | C6B53F669DA11C1FAF4F7DE4 /* Images.xcassets */, 82 | C6B53BC2F791CF18B27CEC35 /* LaunchScreen.xib */, 83 | C6B5365609B299B399A82E17 /* AppDelegate.swift */, 84 | C6B53B146074C0922474E6DB /* Main.storyboard */, 85 | C6B533F81216A87853F21C19 /* ViewController.swift */, 86 | C6B53290F4EE496024C9E6DC /* BLEMingle.swift */, 87 | C6B532DDF8E57F1D39796DBD /* BLECentralDelegate.swift */, 88 | ); 89 | path = BLEMingleiOS; 90 | sourceTree = ""; 91 | }; 92 | C6B53F873D693F3D16B75CB3 /* Products */ = { 93 | isa = PBXGroup; 94 | children = ( 95 | C6B53C549156A54E0778B8BA /* BLEMingleiOS.app */, 96 | ); 97 | name = Products; 98 | sourceTree = ""; 99 | }; 100 | /* End PBXGroup section */ 101 | 102 | /* Begin PBXNativeTarget section */ 103 | C6B53501502AC80DD49A29CC /* BLEMingleiOS */ = { 104 | isa = PBXNativeTarget; 105 | buildConfigurationList = C6B5317EE611F4639FEBA0B2 /* Build configuration list for PBXNativeTarget "BLEMingleiOS" */; 106 | buildPhases = ( 107 | C6B53B1974404B3CED9D8C9E /* Sources */, 108 | C6B5349EB3D7A54922266B9C /* Frameworks */, 109 | C6B5349A3BA54B31B0849F1A /* Resources */, 110 | ); 111 | buildRules = ( 112 | ); 113 | dependencies = ( 114 | ); 115 | name = BLEMingleiOS; 116 | productName = BLEMingleiOS; 117 | productReference = C6B53C549156A54E0778B8BA /* BLEMingleiOS.app */; 118 | productType = "com.apple.product-type.application"; 119 | }; 120 | C6B5365437F0CC3637422F88 /* BLEMingleiOSTests */ = { 121 | isa = PBXNativeTarget; 122 | buildConfigurationList = C6B536DAF752994516A8545E /* Build configuration list for PBXNativeTarget "BLEMingleiOSTests" */; 123 | buildPhases = ( 124 | C6B53DC15DEE19042920968D /* Sources */, 125 | C6B53724F3F9FA07BF34FD28 /* Frameworks */, 126 | C6B539F02D193FE677F0461A /* Resources */, 127 | ); 128 | buildRules = ( 129 | ); 130 | dependencies = ( 131 | C6B5336247381F881C1AEBB4 /* PBXTargetDependency */, 132 | ); 133 | name = BLEMingleiOSTests; 134 | productName = BLEMingleiOSTests; 135 | productType = "com.apple.product-type.bundle.unit-test"; 136 | }; 137 | /* End PBXNativeTarget section */ 138 | 139 | /* Begin PBXProject section */ 140 | C6B53155DE36BC07F1E0969F /* Project object */ = { 141 | isa = PBXProject; 142 | attributes = { 143 | LastSwiftUpdateCheck = 0700; 144 | LastUpgradeCheck = 0800; 145 | ORGANIZATIONNAME = BitGarage; 146 | TargetAttributes = { 147 | C6B53501502AC80DD49A29CC = { 148 | LastSwiftMigration = 0800; 149 | }; 150 | }; 151 | }; 152 | buildConfigurationList = C6B537C117B77E7B70CDEF0C /* Build configuration list for PBXProject "BLEMingleiOS" */; 153 | compatibilityVersion = "Xcode 8.0"; 154 | developmentRegion = English; 155 | hasScannedForEncodings = 0; 156 | knownRegions = ( 157 | en, 158 | ); 159 | mainGroup = C6B531652B6EF3ADD201724D; 160 | productRefGroup = C6B53F873D693F3D16B75CB3 /* Products */; 161 | projectDirPath = ""; 162 | projectRoot = ""; 163 | targets = ( 164 | C6B53501502AC80DD49A29CC /* BLEMingleiOS */, 165 | C6B5365437F0CC3637422F88 /* BLEMingleiOSTests */, 166 | ); 167 | }; 168 | /* End PBXProject section */ 169 | 170 | /* Begin PBXResourcesBuildPhase section */ 171 | C6B5349A3BA54B31B0849F1A /* Resources */ = { 172 | isa = PBXResourcesBuildPhase; 173 | buildActionMask = 2147483647; 174 | files = ( 175 | C6B53F1817DD2F23C25C7A1D /* Images.xcassets in Resources */, 176 | C6B53EBBEEF22DD820FED288 /* LaunchScreen.xib in Resources */, 177 | C6B53BE00254A80475662DB5 /* Main.storyboard in Resources */, 178 | ); 179 | runOnlyForDeploymentPostprocessing = 0; 180 | }; 181 | C6B539F02D193FE677F0461A /* Resources */ = { 182 | isa = PBXResourcesBuildPhase; 183 | buildActionMask = 2147483647; 184 | files = ( 185 | ); 186 | runOnlyForDeploymentPostprocessing = 0; 187 | }; 188 | /* End PBXResourcesBuildPhase section */ 189 | 190 | /* Begin PBXSourcesBuildPhase section */ 191 | C6B53B1974404B3CED9D8C9E /* Sources */ = { 192 | isa = PBXSourcesBuildPhase; 193 | buildActionMask = 2147483647; 194 | files = ( 195 | C6B5378475849A5F25B4BCEE /* AppDelegate.swift in Sources */, 196 | C6B5318859EA97BB636A8732 /* ViewController.swift in Sources */, 197 | C6B5327D61B61344D39AD70A /* BLEMingle.swift in Sources */, 198 | C6B53998A54B598D73E39B10 /* BLECentralDelegate.swift in Sources */, 199 | ); 200 | runOnlyForDeploymentPostprocessing = 0; 201 | }; 202 | C6B53DC15DEE19042920968D /* Sources */ = { 203 | isa = PBXSourcesBuildPhase; 204 | buildActionMask = 2147483647; 205 | files = ( 206 | C6B53A2DC8725D2896EE0E7A /* BLEMingle.swift in Sources */, 207 | C6B53BF0410A2118C8757C79 /* BLECentralDelegate.swift in Sources */, 208 | ); 209 | runOnlyForDeploymentPostprocessing = 0; 210 | }; 211 | /* End PBXSourcesBuildPhase section */ 212 | 213 | /* Begin PBXTargetDependency section */ 214 | C6B5336247381F881C1AEBB4 /* PBXTargetDependency */ = { 215 | isa = PBXTargetDependency; 216 | target = C6B53501502AC80DD49A29CC /* BLEMingleiOS */; 217 | targetProxy = C6B533792402EEC578E6F23B /* PBXContainerItemProxy */; 218 | }; 219 | /* End PBXTargetDependency section */ 220 | 221 | /* Begin PBXVariantGroup section */ 222 | C6B53B146074C0922474E6DB /* Main.storyboard */ = { 223 | isa = PBXVariantGroup; 224 | children = ( 225 | C6B531CF1BB813835FC07E49 /* Base */, 226 | ); 227 | name = Main.storyboard; 228 | sourceTree = ""; 229 | }; 230 | C6B53BC2F791CF18B27CEC35 /* LaunchScreen.xib */ = { 231 | isa = PBXVariantGroup; 232 | children = ( 233 | C6B535513310D10E6D1577F1 /* Base */, 234 | ); 235 | name = LaunchScreen.xib; 236 | sourceTree = ""; 237 | }; 238 | /* End PBXVariantGroup section */ 239 | 240 | /* Begin XCBuildConfiguration section */ 241 | C6B531D0B00B681BF39BA229 /* Debug */ = { 242 | isa = XCBuildConfiguration; 243 | buildSettings = { 244 | ALWAYS_SEARCH_USER_PATHS = NO; 245 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 246 | CLANG_CXX_LIBRARY = "libc++"; 247 | CLANG_ENABLE_MODULES = YES; 248 | CLANG_ENABLE_OBJC_ARC = YES; 249 | CLANG_WARN_BOOL_CONVERSION = YES; 250 | CLANG_WARN_CONSTANT_CONVERSION = YES; 251 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 252 | CLANG_WARN_EMPTY_BODY = YES; 253 | CLANG_WARN_ENUM_CONVERSION = YES; 254 | CLANG_WARN_INFINITE_RECURSION = YES; 255 | CLANG_WARN_INT_CONVERSION = YES; 256 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 257 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 258 | CLANG_WARN_UNREACHABLE_CODE = YES; 259 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 260 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 261 | COPY_PHASE_STRIP = NO; 262 | ENABLE_STRICT_OBJC_MSGSEND = YES; 263 | ENABLE_TESTABILITY = YES; 264 | GCC_C_LANGUAGE_STANDARD = gnu99; 265 | GCC_DYNAMIC_NO_PIC = NO; 266 | GCC_NO_COMMON_BLOCKS = YES; 267 | GCC_OPTIMIZATION_LEVEL = 0; 268 | GCC_PREPROCESSOR_DEFINITIONS = ( 269 | "DEBUG=1", 270 | "$(inherited)", 271 | ); 272 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 273 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 274 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 275 | GCC_WARN_UNDECLARED_SELECTOR = YES; 276 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 277 | GCC_WARN_UNUSED_FUNCTION = YES; 278 | GCC_WARN_UNUSED_VARIABLE = YES; 279 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 280 | MTL_ENABLE_DEBUG_INFO = YES; 281 | ONLY_ACTIVE_ARCH = YES; 282 | SDKROOT = iphoneos; 283 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 284 | TARGETED_DEVICE_FAMILY = "1,2"; 285 | }; 286 | name = Debug; 287 | }; 288 | C6B5327E691ECDE289A63404 /* Release */ = { 289 | isa = XCBuildConfiguration; 290 | buildSettings = { 291 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 292 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 293 | CODE_SIGN_IDENTITY = "iPhone Developer"; 294 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 295 | DEVELOPMENT_TEAM = J26D86F62R; 296 | INFOPLIST_FILE = BLEMingleiOS/Info.plist; 297 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 298 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 299 | PRODUCT_BUNDLE_IDENTIFIER = BLEMingle; 300 | PRODUCT_NAME = "$(TARGET_NAME)"; 301 | PROVISIONING_PROFILE = ""; 302 | SWIFT_VERSION = 3.0; 303 | TARGETED_DEVICE_FAMILY = 1; 304 | }; 305 | name = Release; 306 | }; 307 | C6B533752BFFA32759B89B50 /* Release */ = { 308 | isa = XCBuildConfiguration; 309 | buildSettings = { 310 | ALWAYS_SEARCH_USER_PATHS = NO; 311 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 312 | CLANG_CXX_LIBRARY = "libc++"; 313 | CLANG_ENABLE_MODULES = YES; 314 | CLANG_ENABLE_OBJC_ARC = YES; 315 | CLANG_WARN_BOOL_CONVERSION = YES; 316 | CLANG_WARN_CONSTANT_CONVERSION = YES; 317 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 318 | CLANG_WARN_EMPTY_BODY = YES; 319 | CLANG_WARN_ENUM_CONVERSION = YES; 320 | CLANG_WARN_INFINITE_RECURSION = YES; 321 | CLANG_WARN_INT_CONVERSION = YES; 322 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 323 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 324 | CLANG_WARN_UNREACHABLE_CODE = YES; 325 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 326 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 327 | COPY_PHASE_STRIP = YES; 328 | ENABLE_NS_ASSERTIONS = NO; 329 | ENABLE_STRICT_OBJC_MSGSEND = YES; 330 | GCC_C_LANGUAGE_STANDARD = gnu99; 331 | GCC_NO_COMMON_BLOCKS = YES; 332 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 333 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 334 | GCC_WARN_UNDECLARED_SELECTOR = YES; 335 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 336 | GCC_WARN_UNUSED_FUNCTION = YES; 337 | GCC_WARN_UNUSED_VARIABLE = YES; 338 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 339 | MTL_ENABLE_DEBUG_INFO = NO; 340 | SDKROOT = iphoneos; 341 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 342 | TARGETED_DEVICE_FAMILY = "1,2"; 343 | VALIDATE_PRODUCT = YES; 344 | }; 345 | name = Release; 346 | }; 347 | C6B533EDBC0AD071B40ADC30 /* Debug */ = { 348 | isa = XCBuildConfiguration; 349 | buildSettings = { 350 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 351 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 352 | CODE_SIGN_IDENTITY = "iPhone Developer"; 353 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 354 | DEVELOPMENT_TEAM = J26D86F62R; 355 | INFOPLIST_FILE = BLEMingleiOS/Info.plist; 356 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 357 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 358 | PRODUCT_BUNDLE_IDENTIFIER = BLEMingle; 359 | PRODUCT_NAME = "$(TARGET_NAME)"; 360 | PROVISIONING_PROFILE = ""; 361 | SWIFT_VERSION = 3.0; 362 | TARGETED_DEVICE_FAMILY = 1; 363 | }; 364 | name = Debug; 365 | }; 366 | C6B5371B2B206705EF955C77 /* Debug */ = { 367 | isa = XCBuildConfiguration; 368 | buildSettings = { 369 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/BLEMingleiOS.app/BLEMingleiOS"; 370 | FRAMEWORK_SEARCH_PATHS = ( 371 | "$(SDKROOT)/Developer/Library/Frameworks", 372 | "$(inherited)", 373 | ); 374 | INFOPLIST_FILE = BLEMingleiOSTests/Info.plist; 375 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 376 | PRODUCT_BUNDLE_IDENTIFIER = "iOS.$(PRODUCT_NAME:rfc1034identifier)"; 377 | PRODUCT_NAME = "$(TARGET_NAME)"; 378 | TEST_HOST = "$(BUNDLE_LOADER)"; 379 | }; 380 | name = Debug; 381 | }; 382 | C6B53D5010D5DEEDB1258A48 /* Release */ = { 383 | isa = XCBuildConfiguration; 384 | buildSettings = { 385 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/BLEMingleiOS.app/BLEMingleiOS"; 386 | FRAMEWORK_SEARCH_PATHS = ( 387 | "$(SDKROOT)/Developer/Library/Frameworks", 388 | "$(inherited)", 389 | ); 390 | INFOPLIST_FILE = BLEMingleiOSTests/Info.plist; 391 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 392 | PRODUCT_BUNDLE_IDENTIFIER = "iOS.$(PRODUCT_NAME:rfc1034identifier)"; 393 | PRODUCT_NAME = "$(TARGET_NAME)"; 394 | TEST_HOST = "$(BUNDLE_LOADER)"; 395 | }; 396 | name = Release; 397 | }; 398 | /* End XCBuildConfiguration section */ 399 | 400 | /* Begin XCConfigurationList section */ 401 | C6B5317EE611F4639FEBA0B2 /* Build configuration list for PBXNativeTarget "BLEMingleiOS" */ = { 402 | isa = XCConfigurationList; 403 | buildConfigurations = ( 404 | C6B533EDBC0AD071B40ADC30 /* Debug */, 405 | C6B5327E691ECDE289A63404 /* Release */, 406 | ); 407 | defaultConfigurationIsVisible = 0; 408 | defaultConfigurationName = Release; 409 | }; 410 | C6B536DAF752994516A8545E /* Build configuration list for PBXNativeTarget "BLEMingleiOSTests" */ = { 411 | isa = XCConfigurationList; 412 | buildConfigurations = ( 413 | C6B5371B2B206705EF955C77 /* Debug */, 414 | C6B53D5010D5DEEDB1258A48 /* Release */, 415 | ); 416 | defaultConfigurationIsVisible = 0; 417 | defaultConfigurationName = Release; 418 | }; 419 | C6B537C117B77E7B70CDEF0C /* Build configuration list for PBXProject "BLEMingleiOS" */ = { 420 | isa = XCConfigurationList; 421 | buildConfigurations = ( 422 | C6B531D0B00B681BF39BA229 /* Debug */, 423 | C6B533752BFFA32759B89B50 /* Release */, 424 | ); 425 | defaultConfigurationIsVisible = 0; 426 | defaultConfigurationName = Release; 427 | }; 428 | /* End XCConfigurationList section */ 429 | }; 430 | rootObject = C6B53155DE36BC07F1E0969F /* Project object */; 431 | } 432 | -------------------------------------------------------------------------------- /BLEMingleiOS.xcodeproj/xcuserdata/michaeloriley.xcuserdatad/xcschemes/BLEMingleiOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | 14 | 20 | 21 | 22 | 28 | 34 | 35 | 36 | 37 | 38 | 43 | 44 | 45 | 46 | 52 | 53 | 54 | 55 | 64 | 65 | 71 | 72 | 73 | 74 | 75 | 76 | 82 | 83 | 89 | 90 | 91 | 92 | 94 | 95 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /BLEMingleiOS/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // BLEMingleiOS 4 | // 5 | // Created by Michael O'Riley on 5/25/15. 6 | // Copyright (c) 2015 BitGarage. All rights reserved. 7 | // 8 | 9 | 10 | import UIKit 11 | 12 | 13 | @UIApplicationMain 14 | class AppDelegate: UIResponder, UIApplicationDelegate { 15 | 16 | 17 | var window: UIWindow? 18 | var bleMingle: BLEMingle! 19 | 20 | 21 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 22 | // Override point for customization after application launch. 23 | return true 24 | } 25 | 26 | 27 | func applicationWillResignActive(_ application: UIApplication) { 28 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 29 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 30 | 31 | } 32 | 33 | 34 | func applicationDidEnterBackground(_ application: UIApplication) { 35 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 36 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 37 | 38 | } 39 | 40 | 41 | func applicationWillEnterForeground(_ application: UIApplication) { 42 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 43 | } 44 | 45 | 46 | func applicationDidBecomeActive(_ application: UIApplication) { 47 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 48 | } 49 | 50 | 51 | func applicationWillTerminate(_ application: UIApplication) { 52 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 53 | } 54 | 55 | 56 | 57 | 58 | } 59 | -------------------------------------------------------------------------------- /BLEMingleiOS/BLECentralDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Michael O'Riley on 5/29/15. 3 | // Copyright (c) 2015 BitGarage. All rights reserved. 4 | // 5 | 6 | import Foundation 7 | import CoreBluetooth 8 | 9 | protocol BLECentralDelegate { 10 | func didDiscoverPeripheral(_ peripheral: CBPeripheral!) 11 | } 12 | -------------------------------------------------------------------------------- /BLEMingleiOS/BLEMingle.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import CoreBluetooth 3 | 4 | extension String { 5 | subscript (r: Range) -> String { 6 | get { 7 | let myNSString = self as NSString 8 | let start = r.lowerBound 9 | let length = r.upperBound - start + 1 10 | return myNSString.substring(with: NSRange(location: start, length: length)) 11 | } 12 | } 13 | 14 | func dataFromHexadecimalString() -> NSData? { 15 | let myNSString = self as NSString 16 | let midString = myNSString.trimmingCharacters(in: NSCharacterSet(charactersIn: "<> ") as CharacterSet) as NSString 17 | let trimmedString = midString.replacingOccurrences(of: " ", with: "") 18 | 19 | // make sure the cleaned up string consists solely of hex digits, and that we have even number of them 20 | 21 | let regex = try! NSRegularExpression(pattern: "^[0-9a-f]*$", 22 | options: [.caseInsensitive]) 23 | 24 | let this_max = trimmedString.characters.count 25 | let found = regex.firstMatch(in: trimmedString, options: NSRegularExpression.MatchingOptions(rawValue: 0), range: NSMakeRange(0, this_max)) 26 | if found == nil || found?.range.location == NSNotFound || this_max % 2 != 0 { 27 | return nil 28 | } 29 | 30 | // everything ok, so now let's build NSData 31 | 32 | let data = NSMutableData(capacity: this_max / 2) 33 | 34 | for i in 0 ..< ((trimmedString.characters.count / 2) - 1) { 35 | let lower = i * 2 36 | let upper = lower + 2 37 | let byteString = trimmedString[lower.. String { 49 | 50 | let string = NSMutableString(capacity: length * 2) 51 | var byte: UInt8 = 0 52 | 53 | for i in 0 ..< length { 54 | getBytes(&byte, range: NSMakeRange(i, 1)) 55 | string.appendFormat("%02x", byte) 56 | } 57 | 58 | return string as String 59 | } 60 | } 61 | 62 | class BLEMingle: NSObject, CBPeripheralManagerDelegate, CBCentralManagerDelegate, CBPeripheralDelegate { 63 | 64 | var peripheralManager: CBPeripheralManager! 65 | var transferCharacteristic: CBMutableCharacteristic! 66 | var dataToSend: NSData! 67 | var sendDataIndex: Int! 68 | var datastring: String! 69 | var sendingEOM: Bool = false 70 | let MAX_TRANSFER_DATA_LENGTH: Int = 20 71 | let TRANSFER_SERVICE_UUID:String = "E20A39F4-73F5-4BC4-A12F-17D1AD07A961" 72 | let TRANSFER_CHARACTERISTIC_UUID:String = "08590F7E-DB05-467E-8757-72F6FAEB13D4" 73 | var centralManager: CBCentralManager! 74 | var discoveredPeripheral: CBPeripheral! 75 | var data: NSMutableData! 76 | var finalString: String! 77 | var lastString: NSString! 78 | var usedList: [String]! 79 | var newList: [String]! 80 | var delegate: BLECentralDelegate? 81 | 82 | override init() { 83 | super.init() 84 | peripheralManager = CBPeripheralManager(delegate: self, queue: nil) 85 | centralManager = CBCentralManager(delegate: self, queue: nil) 86 | data = NSMutableData() 87 | finalString = "" 88 | lastString = "" 89 | usedList = ["Zygats","Quiltiberry"] 90 | newList = usedList 91 | print("initCentral") 92 | } 93 | 94 | func startScan() { 95 | centralManager.scanForPeripherals(withServices: nil, options: [CBCentralManagerScanOptionAllowDuplicatesKey: true]) 96 | 97 | print("Scanning started") 98 | } 99 | 100 | func didDiscoverPeripheral(peripheral: CBPeripheral!) -> CBPeripheral! { 101 | if (peripheral != nil) 102 | { 103 | return peripheral; 104 | } 105 | return nil 106 | } 107 | 108 | func stopScan() { 109 | centralManager.stopScan() 110 | 111 | print("Scanning stopped") 112 | } 113 | 114 | func centralManagerDidUpdateState(_ central: CBCentralManager) { 115 | 116 | } 117 | 118 | func hexToScalar(char: String) -> UnicodeScalar { 119 | var total = 0 120 | for scalar in char.uppercased().unicodeScalars { 121 | if !(scalar >= "A" && scalar <= "F" || scalar >= "0" && scalar <= "9") { 122 | assertionFailure("Input is wrong") 123 | } 124 | 125 | if scalar >= "A" { 126 | total = 16 * total + 10 + Int(scalar.value) - 65 /* 'A' */ 127 | } else { 128 | total = 16 * total + Int(scalar.value) - 48 /* '0' */ 129 | } 130 | } 131 | return UnicodeScalar(total)! 132 | } 133 | 134 | func centralManager(_: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi: NSNumber){ 135 | 136 | delegate?.didDiscoverPeripheral(peripheral) 137 | let splitUp : [String] = "\(advertisementData)".components(separatedBy: "\n") 138 | if (splitUp.count > 1) 139 | { 140 | var chop = splitUp[1] 141 | let counter = chop.characters.count - 2 142 | chop = chop[0.. 1 && chopSplit[1] == "Device Information") 146 | { 147 | let hexString = chop[4..<7] + chop[12..<19] + chop[21..<26] 148 | let hexArray = [hexString[0..<1], hexString[2..<3], hexString[4..<5], hexString[6..<7], hexString[8..<9], hexString[10..<11], hexString[12..<13], hexString[14..<15], hexString[16..<17]] 149 | let charArray = hexArray.map { Character(hexToScalar(char: $0)) } 150 | var string = String(charArray) as String? 151 | if (string == nil) { 152 | } else if (!usedList.contains(string!)) 153 | { 154 | usedList.append(string!) 155 | let this_count = string!.characters.count 156 | if (this_count == 9 && string![this_count-1.. String 250 | { 251 | var rev = String(hex.characters.reversed()) 252 | let hexData: NSData! = rev.data(using: String.Encoding.utf8, allowLossyConversion: false) as NSData! 253 | rev = hexData.toHexString() 254 | while(rev.characters.count < 32) { 255 | rev = "0" + rev; 256 | } 257 | rev = rev[0..<31] 258 | let finalString = rev[0..<7] + "-" + rev[8..<11] + "-" + rev[12..<15] + "-" + rev[16..<19] + "-" + rev[20..<31] 259 | return finalString 260 | } 261 | 262 | class var sharedInstance: BLEMingle { 263 | struct Static { 264 | static let instance: BLEMingle = BLEMingle() 265 | } 266 | return Static.instance 267 | } 268 | 269 | func sendDataToPeripheral(data: NSData) { 270 | dataToSend = data 271 | startAdvertisingToPeripheral() 272 | } 273 | 274 | func startAdvertisingToPeripheral() { 275 | if (dataToSend != nil) 276 | { 277 | datastring = NSString(data:dataToSend as Data, encoding:String.Encoding.utf8.rawValue) as! String 278 | datastring = "iPhone: " + datastring 279 | let count = Double(datastring.characters.count) 280 | for i in 0.. 14) 285 | { 286 | let piece = datastring[(14 * i)..<(14 * (i + 1) - 1)] + "-" 287 | DispatchQueue.main.asyncAfter(deadline: time) { 288 | () -> Void in self.sendMessage(message: piece); 289 | } 290 | } 291 | else 292 | { 293 | let piece = datastring[(14 * i)..<(datastring.characters.count-1)] 294 | DispatchQueue.main.asyncAfter(deadline: time) { 295 | () -> Void in self.sendMessage(message: piece); 296 | } 297 | DispatchQueue.main.asyncAfter(deadline: stop) { 298 | () -> Void in self.peripheralManager.stopAdvertising(); 299 | } 300 | } 301 | } 302 | } 303 | } 304 | 305 | func sendMessage(message: String) 306 | { 307 | let messageUUID = StringToUUID(hex: message) 308 | 309 | peripheralManager.stopAdvertising() 310 | peripheralManager.startAdvertising([CBAdvertisementDataServiceUUIDsKey: [CBUUID(string: messageUUID)]]) 311 | } 312 | 313 | func peripheralManagerDidUpdateState(_ peripheral: CBPeripheralManager) { 314 | 315 | if #available(iOS 10.0, *) { 316 | if peripheral.state != CBManagerState.poweredOn { 317 | return 318 | } 319 | } else { 320 | // Fallback on earlier versions 321 | } 322 | 323 | print("self.peripheralManager powered on.") 324 | 325 | transferCharacteristic = CBMutableCharacteristic(type: CBUUID(string: TRANSFER_CHARACTERISTIC_UUID), properties: CBCharacteristicProperties.notify, value: nil, permissions: CBAttributePermissions.readable) 326 | 327 | let transferService = CBMutableService(type: CBUUID(string: TRANSFER_SERVICE_UUID), primary: true) 328 | 329 | transferService.characteristics = [transferCharacteristic] 330 | 331 | peripheralManager.add(transferService) 332 | 333 | } 334 | 335 | func peripheralManager(peripheral: CBPeripheralManager, central: CBCentral, didSubscribeToCharacteristic characteristic: CBCharacteristic) { 336 | 337 | print("Central subscribed to characteristic: \(characteristic)") 338 | } 339 | 340 | func peripheralManager(peripheral: CBPeripheralManager, central: CBCentral, didUnsubscribeFromCharacteristic characteristic: CBCharacteristic) { 341 | 342 | print("Central unsubscribed from characteristic") 343 | } 344 | 345 | func transferData() { 346 | if sendingEOM { 347 | 348 | var didSend:Bool = peripheralManager.updateValue("EOM".data(using: String.Encoding.utf8)!, for: transferCharacteristic, onSubscribedCentrals: nil) 349 | 350 | if didSend { 351 | 352 | sendingEOM = false 353 | print("sending EOM") 354 | //sleep(10000) 355 | peripheralManager.stopAdvertising() 356 | } 357 | 358 | return 359 | } 360 | 361 | if sendDataIndex >= dataToSend.length { 362 | return 363 | } 364 | 365 | var didSend:Bool = true 366 | 367 | while(didSend) { 368 | var amountToSend:Int = dataToSend.length - sendDataIndex 369 | 370 | if amountToSend > MAX_TRANSFER_DATA_LENGTH { 371 | amountToSend = MAX_TRANSFER_DATA_LENGTH 372 | } 373 | 374 | var chunk = NSData(bytes: dataToSend.bytes + sendDataIndex, length: amountToSend) 375 | print("chunk: \(NSString(data: chunk as Data, encoding: String.Encoding.utf8.rawValue)!)") 376 | 377 | didSend = peripheralManager.updateValue(chunk as Data, for: transferCharacteristic, onSubscribedCentrals: nil) 378 | 379 | if !didSend { 380 | print("didnotsend") 381 | return; 382 | } 383 | 384 | var stringFromData = NSString(data: chunk as Data, encoding: String.Encoding.utf8.rawValue) 385 | print("Sent: " + (stringFromData! as String)) 386 | 387 | sendDataIndex = sendDataIndex + amountToSend 388 | 389 | if sendDataIndex >= dataToSend.length { 390 | sendingEOM = true 391 | 392 | let eomSent = peripheralManager.updateValue("EOM".data(using: String.Encoding.utf8)!, for: transferCharacteristic, onSubscribedCentrals: nil) 393 | 394 | if eomSent { 395 | sendingEOM = false 396 | print("Sending EOM") 397 | } 398 | 399 | return 400 | } 401 | } 402 | } 403 | 404 | func peripheralManagerIsReadyToUpdateSubscribers(peripheral: CBPeripheralManager) { 405 | print("Ready to transfer") 406 | transferData() 407 | } 408 | } 409 | -------------------------------------------------------------------------------- /BLEMingleiOS/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /BLEMingleiOS/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /BLEMingleiOS/Images.xcassets/AppIcon.appiconset/120-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitgarage/BLEMingleiOS/382f0fe28d51ca6dae8455ffb93aae13a9749160/BLEMingleiOS/Images.xcassets/AppIcon.appiconset/120-1.png -------------------------------------------------------------------------------- /BLEMingleiOS/Images.xcassets/AppIcon.appiconset/120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitgarage/BLEMingleiOS/382f0fe28d51ca6dae8455ffb93aae13a9749160/BLEMingleiOS/Images.xcassets/AppIcon.appiconset/120.png -------------------------------------------------------------------------------- /BLEMingleiOS/Images.xcassets/AppIcon.appiconset/180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitgarage/BLEMingleiOS/382f0fe28d51ca6dae8455ffb93aae13a9749160/BLEMingleiOS/Images.xcassets/AppIcon.appiconset/180.png -------------------------------------------------------------------------------- /BLEMingleiOS/Images.xcassets/AppIcon.appiconset/58.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitgarage/BLEMingleiOS/382f0fe28d51ca6dae8455ffb93aae13a9749160/BLEMingleiOS/Images.xcassets/AppIcon.appiconset/58.png -------------------------------------------------------------------------------- /BLEMingleiOS/Images.xcassets/AppIcon.appiconset/80.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitgarage/BLEMingleiOS/382f0fe28d51ca6dae8455ffb93aae13a9749160/BLEMingleiOS/Images.xcassets/AppIcon.appiconset/80.png -------------------------------------------------------------------------------- /BLEMingleiOS/Images.xcassets/AppIcon.appiconset/87.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitgarage/BLEMingleiOS/382f0fe28d51ca6dae8455ffb93aae13a9749160/BLEMingleiOS/Images.xcassets/AppIcon.appiconset/87.png -------------------------------------------------------------------------------- /BLEMingleiOS/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "size" : "29x29", 15 | "idiom" : "iphone", 16 | "filename" : "58.png", 17 | "scale" : "2x" 18 | }, 19 | { 20 | "size" : "29x29", 21 | "idiom" : "iphone", 22 | "filename" : "87.png", 23 | "scale" : "3x" 24 | }, 25 | { 26 | "size" : "40x40", 27 | "idiom" : "iphone", 28 | "filename" : "80.png", 29 | "scale" : "2x" 30 | }, 31 | { 32 | "size" : "40x40", 33 | "idiom" : "iphone", 34 | "filename" : "120.png", 35 | "scale" : "3x" 36 | }, 37 | { 38 | "size" : "60x60", 39 | "idiom" : "iphone", 40 | "filename" : "120-1.png", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "size" : "60x60", 45 | "idiom" : "iphone", 46 | "filename" : "180.png", 47 | "scale" : "3x" 48 | }, 49 | { 50 | "idiom" : "ipad", 51 | "size" : "20x20", 52 | "scale" : "1x" 53 | }, 54 | { 55 | "idiom" : "ipad", 56 | "size" : "20x20", 57 | "scale" : "2x" 58 | }, 59 | { 60 | "idiom" : "ipad", 61 | "size" : "29x29", 62 | "scale" : "1x" 63 | }, 64 | { 65 | "idiom" : "ipad", 66 | "size" : "29x29", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "idiom" : "ipad", 71 | "size" : "40x40", 72 | "scale" : "1x" 73 | }, 74 | { 75 | "idiom" : "ipad", 76 | "size" : "40x40", 77 | "scale" : "2x" 78 | }, 79 | { 80 | "idiom" : "ipad", 81 | "size" : "76x76", 82 | "scale" : "1x" 83 | }, 84 | { 85 | "idiom" : "ipad", 86 | "size" : "76x76", 87 | "scale" : "2x" 88 | }, 89 | { 90 | "idiom" : "ipad", 91 | "size" : "83.5x83.5", 92 | "scale" : "2x" 93 | } 94 | ], 95 | "info" : { 96 | "version" : 1, 97 | "author" : "xcode" 98 | } 99 | } -------------------------------------------------------------------------------- /BLEMingleiOS/Images.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "portrait", 5 | "idiom" : "ipad", 6 | "extent" : "full-screen", 7 | "minimum-system-version" : "7.0", 8 | "scale" : "1x" 9 | }, 10 | { 11 | "orientation" : "landscape", 12 | "idiom" : "ipad", 13 | "extent" : "full-screen", 14 | "minimum-system-version" : "7.0", 15 | "scale" : "1x" 16 | }, 17 | { 18 | "orientation" : "portrait", 19 | "idiom" : "ipad", 20 | "extent" : "full-screen", 21 | "minimum-system-version" : "7.0", 22 | "scale" : "2x" 23 | }, 24 | { 25 | "orientation" : "landscape", 26 | "idiom" : "ipad", 27 | "extent" : "full-screen", 28 | "minimum-system-version" : "7.0", 29 | "scale" : "2x" 30 | } 31 | ], 32 | "info" : { 33 | "version" : 1, 34 | "author" : "xcode" 35 | } 36 | } -------------------------------------------------------------------------------- /BLEMingleiOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | BLEMingle 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 2.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 16 25 | LSRequiresIPhoneOS 26 | 27 | NSBluetoothPeripheralUsageDescription 28 | It uses bluetooth to communicate 29 | UILaunchStoryboardName 30 | Main 31 | UIMainStoryboardFile 32 | Main 33 | UIRequiredDeviceCapabilities 34 | 35 | armv7 36 | 37 | UISupportedInterfaceOrientations 38 | 39 | UIInterfaceOrientationPortrait 40 | 41 | UISupportedInterfaceOrientations~ipad 42 | 43 | UIInterfaceOrientationPortrait 44 | UIInterfaceOrientationPortraitUpsideDown 45 | UIInterfaceOrientationLandscapeLeft 46 | UIInterfaceOrientationLandscapeRight 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /BLEMingleiOS/ViewController.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import CoreBluetooth 3 | 4 | class ViewController: UIViewController, UITextViewDelegate { 5 | 6 | @IBOutlet var textView: UITextView! 7 | @IBOutlet var Abel: UISwitch! 8 | var bleMingle: BLEMingle! 9 | 10 | func toggleSwitch() { 11 | var lastMessage = "" 12 | var allText = "" 13 | bleMingle.startScan() 14 | let priority = DispatchQueue.GlobalQueuePriority.default 15 | DispatchQueue.global(priority: priority).async { 16 | while (true) 17 | { 18 | let temp:String = self.bleMingle.lastString as String 19 | if (temp != lastMessage && temp != "") 20 | { 21 | DispatchQueue.main.async { 22 | allText = allText + temp 23 | self.updateView(allText) 24 | } 25 | lastMessage = temp 26 | } 27 | } 28 | } 29 | } 30 | 31 | @IBAction func sendData(_ sender: AnyObject) { 32 | let dataToSend = textView.text.data(using: String.Encoding.utf8) 33 | 34 | bleMingle.sendDataToPeripheral(data: dataToSend! as NSData) 35 | textView.text = "" 36 | } 37 | 38 | func updateView(_ message: String) { 39 | let textView2 = self.view.viewWithTag(2) as! UITextView 40 | textView2.text = message 41 | } 42 | 43 | override func viewDidLoad() { 44 | super.viewDidLoad() 45 | 46 | bleMingle = BLEMingle() 47 | textView.delegate = self 48 | 49 | let delay = 2.000 * Double(NSEC_PER_SEC) 50 | let time = DispatchTime.now() + Double(Int64(delay)) / Double(NSEC_PER_SEC) 51 | DispatchQueue.main.asyncAfter(deadline: time, execute: { () -> Void in self.toggleSwitch() }); 52 | 53 | } 54 | 55 | override func viewDidAppear(_ animated: Bool) { 56 | } 57 | 58 | override func didReceiveMemoryWarning() { 59 | super.didReceiveMemoryWarning() 60 | } 61 | 62 | // override func touchesBegan(touches: NSSet, withEvent event: UIEvent) { 63 | // self.view.endEditing(true) 64 | // } 65 | } 66 | -------------------------------------------------------------------------------- /BLEMingleiOSTests/BLEMingleiOSTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BLEMingleiOSTests.swift 3 | // BLEMingleiOSTests 4 | // 5 | // Created by Michael O'Riley on 5/24/15. 6 | // Copyright (c) 2015 BitGarage. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import XCTest 11 | 12 | class BLEMingleiOSTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | 24 | func testExample() { 25 | // This is an example of a functional test case. 26 | XCTAssert(true, "Pass") 27 | } 28 | 29 | func testPerformanceExample() { 30 | // This is an example of a performance test case. 31 | self.measureBlock() { 32 | // Put the code you want to measure the time of here. 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /BLEMingleiOSTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | ![alt android](https://s3-us-west-2.amazonaws.com/assets-japanfour/androidmingleble.png) 2 | ![alt ios](https://s3-us-west-2.amazonaws.com/assets-japanfour/iosmingleble.png) --------------------------------------------------------------------------------