Puppet: updated help

Manual Scanner: fix table layout warnings while in background
Simulated target: handle disconnections
This commit is contained in:
Antonio 2020-02-08 18:45:41 +01:00
parent f75db839ff
commit 170809c2f8
20 changed files with 344 additions and 259 deletions

View file

@ -28,6 +28,8 @@
<string>This app needs access to Bluetooth to connect to Circuit Playground Bluefruit devices</string>
<key>NSBluetoothPeripheralUsageDescription</key>
<string>This app needs access to Bluetooth to connect to Circuit Playground Bluefruit devices</string>
<key>NSCameraUsageDescription</key>
<string>Puppet module requires access to the camera</string>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>

View file

@ -1347,7 +1347,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 12;
CURRENT_PROJECT_VERSION = 13;
DEVELOPMENT_TEAM = 2X94RM7457;
INFOPLIST_FILE = BluefruitPlayground/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
@ -1372,7 +1372,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 12;
CURRENT_PROJECT_VERSION = 13;
DEVELOPMENT_TEAM = 2X94RM7457;
INFOPLIST_FILE = BluefruitPlayground/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
@ -1436,7 +1436,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 12;
CURRENT_PROJECT_VERSION = 13;
DEVELOPMENT_TEAM = 2X94RM7457;
INFOPLIST_FILE = "BluefruitPlayground-SimulatedBluetooth-Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
@ -1446,7 +1446,7 @@
);
MARKETING_VERSION = 1.2.0;
OTHER_SWIFT_FLAGS = "$(inherited) -D COCOAPODS -D SIMULATEBLUETOOTH";
PRODUCT_BUNDLE_IDENTIFIER = com.adafruit.BluefruitPlayground;
PRODUCT_BUNDLE_IDENTIFIER = com.adafruit.BluefruitPlayground.simulated;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "BluefruitPlayground/BluefruitPlayground-SimulateBluetooth-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
@ -1462,7 +1462,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 12;
CURRENT_PROJECT_VERSION = 13;
DEVELOPMENT_TEAM = 2X94RM7457;
INFOPLIST_FILE = "BluefruitPlayground-SimulatedBluetooth-Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
@ -1472,7 +1472,7 @@
);
MARKETING_VERSION = 1.2.0;
OTHER_SWIFT_FLAGS = "$(inherited) -D COCOAPODS -D SIMULATEBLUETOOTH";
PRODUCT_BUNDLE_IDENTIFIER = com.adafruit.BluefruitPlayground;
PRODUCT_BUNDLE_IDENTIFIER = com.adafruit.BluefruitPlayground.simulated;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "BluefruitPlayground/BluefruitPlayground-SimulateBluetooth-Bridging-Header.h";
SWIFT_VERSION = 5.0;

View file

@ -38,7 +38,7 @@ class BleManager: NSObject {
internal var scanningStartTime: TimeInterval? // Time when the scanning started. nil if stopped
private var scanningServicesFilter: [CBUUID]?
internal var peripheralsFound = [UUID: BlePeripheral]()
private var peripheralsFoundLock = NSLock()
internal var peripheralsFoundLock = NSLock()
// Connecting
private var connectionTimeoutTimers = [UUID: MSWeakTimer]()
@ -353,6 +353,10 @@ extension BleManager: CBCentralManagerDelegate {
func centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?) {
DLog("didFailToConnect")
// Clean
peripheralsFound[peripheral.identifier]?.reset()
// Notify
NotificationCenter.default.post(name: .didDisconnectFromPeripheral, object: nil, userInfo: [NotificationUserInfoKey.uuid.rawValue: peripheral.identifier])
}

View file

@ -337,7 +337,7 @@ class BlePeripheral: NSObject {
}
// MARK: - Command Queue
private class BleCommand: Equatable {
internal class BleCommand: Equatable {
enum CommandType {
case discoverService
case discoverCharacteristic
@ -404,7 +404,7 @@ class BlePeripheral: NSObject {
return "\(descriptor.characteristic.service.uuid.uuidString)-\(descriptor.characteristic.uuid.uuidString)-\(descriptor.uuid.uuidString)"
}
private func finishedExecutingCommand(error: Error?) {
internal func finishedExecutingCommand(error: Error?) {
//DLog("finishedExecutingCommand")
// Result Callback
@ -523,7 +523,7 @@ class BlePeripheral: NSObject {
peripheral.readValue(for: descriptor)
}
private func disconnect(with command: BleCommand) {
internal func disconnect(with command: BleCommand) {
let centralManager = command.parameters!.first as! CBCentralManager
centralManager.cancelPeripheralConnection(self.peripheral)
finishedExecutingCommand(error: nil)

View file

@ -19,6 +19,7 @@ class BleManagerSimulated: BleManager {
}
// MARK: - Scanning
override func startScan(withServices services: [CBUUID]? = nil) {
scanningStartTime = CACurrentMediaTime()
@ -31,8 +32,12 @@ class BleManagerSimulated: BleManager {
override func stopScan() {
}
// MARK: - Connect
override func connect(to peripheral: BlePeripheral, timeout: TimeInterval? = nil, shouldNotifyOnConnection: Bool = false, shouldNotifyOnDisconnection: Bool = false, shouldNotifyOnNotification: Bool = false) {
guard let blePeripheral = peripheral as? BlePeripheralSimulated else { return }
blePeripheral.simulateConnect()
// Send notification
NotificationCenter.default.post(name: .didConnectToPeripheral, object: nil, userInfo: [NotificationUserInfoKey.uuid.rawValue: peripheral.identifier])
}
@ -40,4 +45,34 @@ class BleManagerSimulated: BleManager {
override func reconnecToPeripherals(withIdentifiers identifiers: [UUID], withServices services: [CBUUID], timeout: Double? = nil) -> Bool {
return false
}
// MARK: - Disconnect
override func disconnect(from peripheral: BlePeripheral, waitForQueuedCommands: Bool = false) {
guard let blePeripheral = peripheral as? BlePeripheralSimulated else { return }
DLog("disconnect")
NotificationCenter.default.post(name: .willDisconnectFromPeripheral, object: nil, userInfo: [NotificationUserInfoKey.uuid.rawValue: peripheral.identifier])
if waitForQueuedCommands {
// Send the disconnection to the command queue, so all the previous command are executed before disconnecting
if let centralManager = centralManager {
blePeripheral.disconnect(centralManager: centralManager)
}
}
else {
didDisconnectPeripheral(blePeripheral: blePeripheral)
}
}
func didDisconnectPeripheral(blePeripheral: BlePeripheralSimulated) {
DLog("didDisconnectPeripheral")
// Clean
peripheralsFound[blePeripheral.identifier]?.reset()
// Notify
NotificationCenter.default.post(name: .didDisconnectFromPeripheral, object: nil, userInfo: [NotificationUserInfoKey.uuid.rawValue: blePeripheral.identifier])
// Don't remove the peripheral from the peripheral list (so we can select again the simulated peripheral)
}
}

View file

@ -10,20 +10,19 @@ import Foundation
import CoreBluetooth
class BlePeripheralSimulated: BlePeripheral {
// Constants
private static let kSimulatedUUID = UUID(uuidString: "E621E1F8-C36C-495A-93FC-0C247A3E6E5F")!
// Data
private var simulatedIdentifier = UUID()
override var identifier: UUID {
return BlePeripheralSimulated.kSimulatedUUID
return simulatedIdentifier
}
override var name: String? {
return "Simulated Peripheral"
}
private var simulatedState: CBPeripheralState = .disconnected
override var state: CBPeripheralState {
return .connected
return simulatedState
}
// MARK: - Lifecycle
@ -46,5 +45,20 @@ class BlePeripheralSimulated: BlePeripheral {
override func discover(serviceUuids: [CBUUID]?, completion: ((Error?) -> Void)?) {
completion?(nil)
}
// MARK: - Connect
func simulateConnect() {
simulatedState = .connected
}
// MARK: - Disconnect
override internal func disconnect(with command: BleCommand) {
// Simulate disconnection
simulatedState = .disconnected
BleManagerSimulated.simulated.didDisconnectPeripheral(blePeripheral: self)
// Finished
finishedExecutingCommand(error: nil)
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

After

Width:  |  Height:  |  Size: 128 KiB

View file

@ -12,6 +12,7 @@
},
{
"idiom" : "universal",
"filename" : "scanproblems_powerup@3x.png",
"scale" : "3x"
}
],

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 120 KiB

After

Width:  |  Height:  |  Size: 124 KiB

File diff suppressed because it is too large Load diff

View file

@ -205,14 +205,13 @@ Download it from the Bluefruit Playground guide at learn.adafruit.com";
// Puppet
"puppet_title" = "Puppets";
"puppet_help_header" = "This Puppet module allows you to animate a 3D puppets in real time using the Circuit Playground Bluefruit board.
"puppet_help_header" = "The Puppets module allows you to animate a 3D puppet in real time using Circuit Playground Bluefruit.
To control the puppet, attach Circuit Playground Bluefruit to the back of your fingers using a rubber band as seen below:";
"puppet_help_details" = "• Tilt your board forward or backwards to open and close the mouth of the puppet(Sparky The Blue Smoke Monster).
• Try turning your board to turn your puppets head left and right.
• Press the A or B button on the board to trigger present animations.
You can also screen record and share your interaction with the puppet.";
To control Sparky the Blue Smoke Monster, attach Circuit Playground Bluefruit to the back of your fingers using a rubber band as seen below:";
"puppet_help_details" = "• Tilt your board forward or backwards to open and close the mouth of the puppet.
• Try tilting your board to tilt the puppets head left or right.
• Press the A or B button on Circuit Playground Bluefruit to trigger preset animations.
• Use the buttons at the bottom to record the screen, change background, camera, & fullscreen mode. ";
"puppet_recording_error_title" = "Recording Error";

View file

@ -43,7 +43,32 @@ class HelpViewController: UIViewController {
loadViewIfNeeded()
let imageView = UIImageView(image: image)
contentStackView.addArrangedSubview(imageView)
imageView.tintColor = UIColor(named: "text_default")
imageView.contentMode = .scaleAspectFit
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.setContentHuggingPriority(UILayoutPriority(rawValue: 1000), for: .vertical)
// Add imageView inside container to adjust proportions
let containerView = UIView()
containerView.backgroundColor = .clear
containerView.addSubview(imageView)
imageView.topAnchor.constraint(equalTo: containerView.topAnchor).isActive = true
imageView.bottomAnchor.constraint(equalTo: containerView.bottomAnchor).isActive = true
imageView.centerXAnchor.constraint(equalTo: containerView.centerXAnchor).isActive = true
//imageView.leadingAnchor.constraint(greaterThanOrEqualTo: containerView.leadingAnchor).isActive = true
//imageView.trailingAnchor.constraint(greaterThanOrEqualTo: containerView.trailingAnchor).isActive = true
let proportionalWidthConstraint = imageView.widthAnchor.constraint(equalTo: containerView.widthAnchor, multiplier: 0.75)
proportionalWidthConstraint.priority = UILayoutPriority(rawValue: 999)
proportionalWidthConstraint.isActive = true
imageView.widthAnchor.constraint(lessThanOrEqualToConstant: 350).isActive = true // Limit image to 350 width
imageView.heightAnchor.constraint(equalTo: imageView.widthAnchor, multiplier: image.size.height / image.size.width).isActive = true
contentStackView.addArrangedSubview(containerView)
}
// MARK: - Actions

View file

@ -62,8 +62,6 @@ class ScannerViewController: UIViewController {
// Hide automatic scanning if needed
scanAutomaticallyButton.isHidden = !Config.isAutomaticConnectionEnabled
// Ble Notifications
registerNotifications(enabled: true)
// Localization
let localizationManager = LocalizationManager.shared
@ -82,7 +80,15 @@ class ScannerViewController: UIViewController {
if let customNavigationBar = navigationController?.navigationBar as? NavigationBarWithScrollAwareRightButton {
customNavigationBar.setRightButton(topViewController: self, image: UIImage(named: "info"), target: self, action: #selector(about(_:)))
}
// Ble Notifications
registerNotifications(enabled: true)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
// Disconnect if needed
let connectedPeripherals = bleManager.connectedPeripherals()
if connectedPeripherals.count == 1, let peripheral = connectedPeripherals.first {
@ -90,10 +96,6 @@ class ScannerViewController: UIViewController {
// Disconnect from peripheral
disconnect(peripheral: peripheral)
}
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
// Update UI
updateScannedPeripherals()
@ -111,6 +113,9 @@ class ScannerViewController: UIViewController {
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
// Ble Notifications
registerNotifications(enabled: false)
// Stop scanning
bleManager.stopScan()
@ -118,11 +123,6 @@ class ScannerViewController: UIViewController {
peripheralList.clear()
}
deinit {
// Ble Notifications
registerNotifications(enabled: false)
}
// MARK: - BLE Notifications
private weak var didDiscoverPeripheralObserver: NSObjectProtocol?
private weak var willConnectToPeripheralObserver: NSObjectProtocol?