Skip to content

Commit

Permalink
#1
Browse files Browse the repository at this point in the history
* added InputTextField to show validation messages on every text field
* changed SystemID Characteristic to use InputTextField
  • Loading branch information
carlos21 committed Jun 27, 2018
1 parent 031d087 commit 49e2979
Show file tree
Hide file tree
Showing 7 changed files with 362 additions and 62 deletions.
12 changes: 12 additions & 0 deletions BluetoothExplorer.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
353557D020E28CD200543440 /* String.swift in Sources */ = {isa = PBXBuildFile; fileRef = 353557CF20E28CD200543440 /* String.swift */; };
353557D620E2D15000543440 /* PnPIDCharacteristic.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 353557D520E2D15000543440 /* PnPIDCharacteristic.storyboard */; };
353557DF20E2D17300543440 /* PnPIDCharacteristicViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 353557DE20E2D17300543440 /* PnPIDCharacteristicViewController.swift */; };
35F5BB5A20E3DAC500AC5FF1 /* InputTextView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 35F5BB5920E3DAC500AC5FF1 /* InputTextView.xib */; };
35F5BB6320E3DB8A00AC5FF1 /* InputTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35F5BB6220E3DB8A00AC5FF1 /* InputTextView.swift */; };
35F5BB6520E3DC0000AC5FF1 /* NibDesignable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35F5BB6420E3DC0000AC5FF1 /* NibDesignable.swift */; };
6E13E8CC20D9C7270007111B /* AdvertisementDataManagedObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E13E8CB20D9C7270007111B /* AdvertisementDataManagedObject.swift */; };
6E13E8E320D9D8290007111B /* TableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E13E8E220D9D8290007111B /* TableViewController.swift */; };
6E353A4620D7FDB200E94B73 /* CoreDataEncodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E353A4520D7FDB200E94B73 /* CoreDataEncodable.swift */; };
Expand Down Expand Up @@ -196,6 +199,9 @@
353557CF20E28CD200543440 /* String.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = String.swift; sourceTree = "<group>"; };
353557D520E2D15000543440 /* PnPIDCharacteristic.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = PnPIDCharacteristic.storyboard; sourceTree = "<group>"; };
353557DE20E2D17300543440 /* PnPIDCharacteristicViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PnPIDCharacteristicViewController.swift; sourceTree = "<group>"; };
35F5BB5920E3DAC500AC5FF1 /* InputTextView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = InputTextView.xib; sourceTree = "<group>"; };
35F5BB6220E3DB8A00AC5FF1 /* InputTextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InputTextView.swift; sourceTree = "<group>"; };
35F5BB6420E3DC0000AC5FF1 /* NibDesignable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NibDesignable.swift; sourceTree = "<group>"; };
6E13E8CB20D9C7270007111B /* AdvertisementDataManagedObject.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdvertisementDataManagedObject.swift; sourceTree = "<group>"; };
6E13E8E220D9D8290007111B /* TableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TableViewController.swift; sourceTree = "<group>"; };
6E353A4520D7FDB200E94B73 /* CoreDataEncodable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoreDataEncodable.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -372,6 +378,9 @@
children = (
6EC0D9C620DE076A005FB128 /* Appearance.swift */,
6EDE00D120DB47FD002E951A /* CustomButton.swift */,
35F5BB5920E3DAC500AC5FF1 /* InputTextView.xib */,
35F5BB6220E3DB8A00AC5FF1 /* InputTextView.swift */,
35F5BB6420E3DC0000AC5FF1 /* NibDesignable.swift */,
);
path = View;
sourceTree = "<group>";
Expand Down Expand Up @@ -610,6 +619,7 @@
35335A1A20E14830006ABD4D /* ManufacturerNameStringCharacteristic.storyboard in Resources */,
35335A1220E13FC0006ABD4D /* FirmwareRevisionStringCharacteristic.storyboard in Resources */,
35335A1620E14353006ABD4D /* SoftwareRevisionStringCharacteristic.storyboard in Resources */,
35F5BB5A20E3DAC500AC5FF1 /* InputTextView.xib in Resources */,
35335A2B20E16D4F006ABD4D /* DateTimeCharacteristic.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down Expand Up @@ -642,6 +652,7 @@
6E8C68E920DA02DA00232169 /* PresentPopover.swift in Sources */,
6EFB3E9520D3EFFB00364CA0 /* PeripheralManagedObject.swift in Sources */,
35335A1C20E14846006ABD4D /* ManufacturerNameStringCharacteristicViewController.swift in Sources */,
35F5BB6320E3DB8A00AC5FF1 /* InputTextView.swift in Sources */,
6ECCCC6E20E091070054663C /* FDStackView.m in Sources */,
6E8C68F220DA340C00232169 /* PeripheralServicesViewController.swift in Sources */,
6E98B6982059B51000B6F016 /* PeripheralsViewController.swift in Sources */,
Expand Down Expand Up @@ -674,6 +685,7 @@
6ECCCC6C20E091070054663C /* FDTransformLayer.m in Sources */,
6E98B6962059B51000B6F016 /* AppDelegate.swift in Sources */,
353557DF20E2D17300543440 /* PnPIDCharacteristicViewController.swift in Sources */,
35F5BB6520E3DC0000AC5FF1 /* NibDesignable.swift in Sources */,
6E8C68E520DA02B600232169 /* ErrorAlert.swift in Sources */,
6ECCCC7020E091070054663C /* FDStackViewAlignmentLayoutArrangement.m in Sources */,
6ECCCC7220E091070054663C /* FDStackViewLayoutArrangement.m in Sources */,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ final class SystemIDCharacteristicViewController: UIViewController, Characterist

// MARK: - IB Outlets

@IBOutlet private(set) var manufacturerIdentifierTextField: UITextField!
@IBOutlet weak var menufacturerIdentifierInputText: InputTextView!

@IBOutlet private(set) var organizationallyUniqueIdentifierTextField: UITextField!
@IBOutlet weak var organizationIdentifierInputText: InputTextView!

// MARK: - Properties

Expand All @@ -29,30 +29,30 @@ final class SystemIDCharacteristicViewController: UIViewController, Characterist
super.viewDidLoad()

configureView()
}

// MARK: - Actions

@IBAction func textFieldEditingChanged(_ sender: Any) {

guard let manufacturerIdentifierText = manufacturerIdentifierTextField.text
else { showErrorAlert("Manufacturer Identifier is mandatory"); return }

guard let organizationallyUniqueIdentifierText = organizationallyUniqueIdentifierTextField.text
else { showErrorAlert("Organization Identifier is mandatory"); return }

guard let manufacturerIdentifier = UInt64(manufacturerIdentifierText)
else { showErrorAlert("The entered number is too long"); return }
menufacturerIdentifierInputText.validator = { value in

guard value.trim() != ""
else { return .none }

// TODO: Use Bluetooth max value
guard let manufacturerIdValue = UInt64(value), manufacturerIdValue <= 1099511627775
else { return .error("Maximum value is \(1099511627775)") }

return .none
}

guard let organizationallyUniqueIdentifier = UInt32(organizationallyUniqueIdentifierText)
else { showErrorAlert("The entered number is too long"); return }

guard let systemID = GATTSystemID(manufacturerIdentifier: manufacturerIdentifier,
organizationallyUniqueIdentifier: organizationallyUniqueIdentifier)
else { return }

value = systemID
valueDidChange?(value)
organizationIdentifierInputText.validator = { value in

guard value.trim() != ""
else { return .none }

// TODO: Use Bluetooth max value
guard let organizationIdvalue = UInt32(value), organizationIdvalue <= 16777215
else { return .error("Maximum value is \(16777215)") }

return .none
}
}

// MARK: - Methods
Expand All @@ -63,16 +63,16 @@ final class SystemIDCharacteristicViewController: UIViewController, Characterist

updateText()

manufacturerIdentifierTextField.keyboardType = .numberPad
organizationallyUniqueIdentifierTextField.keyboardType = .numberPad
menufacturerIdentifierInputText.keyboardType = .numberPad
organizationIdentifierInputText.keyboardType = .numberPad
}

private func updateText() {

manufacturerIdentifierTextField.isEnabled = valueDidChange != nil
organizationallyUniqueIdentifierTextField.isEnabled = valueDidChange != nil
manufacturerIdentifierTextField.text = "\(value.manufacturerIdentifier)"
organizationallyUniqueIdentifierTextField.text = "\(value.organizationallyUniqueIdentifier)"
menufacturerIdentifierInputText.isEnabled = valueDidChange != nil
organizationIdentifierInputText.isEnabled = valueDidChange != nil

menufacturerIdentifierInputText.value = "\(value.manufacturerIdentifier)"
organizationIdentifierInputText.value = "\(value.organizationallyUniqueIdentifier)"
}
}
6 changes: 6 additions & 0 deletions BluetoothExplorer/Extensions/String.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,13 @@ import Foundation
public extension String {

func text(before text: String) -> String? {

guard let range = self.range(of: text) else { return nil }
return String(self[self.startIndex..<range.lowerBound])
}

func trim() -> String {

return self.trimmingCharacters(in: CharacterSet.whitespaces)
}
}
79 changes: 48 additions & 31 deletions BluetoothExplorer/SystemIDCharacteristic.storyboard
Original file line number Diff line number Diff line change
Expand Up @@ -21,51 +21,68 @@
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Organizational Identifier" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="e8v-xh-WaS" userLabel="Organizational Identifier Text field">
<rect key="frame" x="16" y="346" width="343" height="35"/>
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="jPp-7O-HKU">
<rect key="frame" x="0.0" y="64" width="375" height="603"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="P08-Mr-Dh9">
<rect key="frame" x="0.0" y="0.0" width="375" height="603"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="hok-5E-9Qf" customClass="InputTextView" customModule="BluetoothExplorer" customModuleProvider="target">
<rect key="frame" x="16" y="16" width="343" height="64"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="placeholder" value="Manufacturer Identifier"/>
<userDefinedRuntimeAttribute type="string" keyPath="fieldLabelText" value="Manufacturer Identifier"/>
</userDefinedRuntimeAttributes>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="OAt-PO-DGR" customClass="InputTextView" customModule="BluetoothExplorer" customModuleProvider="target">
<rect key="frame" x="16" y="110" width="343" height="64"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="placeholder" value="Organization Identifier"/>
<userDefinedRuntimeAttribute type="string" keyPath="fieldLabelText" value="Organization Identifier"/>
</userDefinedRuntimeAttributes>
</view>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="trailing" secondItem="hok-5E-9Qf" secondAttribute="trailing" constant="16" id="ExY-58-BUo"/>
<constraint firstItem="hok-5E-9Qf" firstAttribute="leading" secondItem="P08-Mr-Dh9" secondAttribute="leading" constant="16" id="JKp-i5-0Mo"/>
<constraint firstItem="hok-5E-9Qf" firstAttribute="top" secondItem="P08-Mr-Dh9" secondAttribute="top" constant="16" id="K9U-sT-Deg"/>
<constraint firstItem="OAt-PO-DGR" firstAttribute="trailing" secondItem="hok-5E-9Qf" secondAttribute="trailing" id="Pqb-YZ-hec"/>
<constraint firstItem="OAt-PO-DGR" firstAttribute="top" secondItem="hok-5E-9Qf" secondAttribute="bottom" constant="30" id="dFb-RW-4GW"/>
<constraint firstItem="OAt-PO-DGR" firstAttribute="leading" secondItem="hok-5E-9Qf" secondAttribute="leading" id="tOr-sn-tNb"/>
</constraints>
</view>
</subviews>
<constraints>
<constraint firstAttribute="height" constant="35" id="AGo-Qy-chN"/>
<constraint firstItem="P08-Mr-Dh9" firstAttribute="top" secondItem="jPp-7O-HKU" secondAttribute="top" id="IxF-OU-TrA"/>
<constraint firstItem="P08-Mr-Dh9" firstAttribute="width" secondItem="jPp-7O-HKU" secondAttribute="width" id="TPl-So-o2B"/>
<constraint firstAttribute="bottom" secondItem="P08-Mr-Dh9" secondAttribute="bottom" id="aFG-o2-7tE"/>
<constraint firstAttribute="trailing" secondItem="P08-Mr-Dh9" secondAttribute="trailing" id="afO-B0-XGg"/>
<constraint firstItem="P08-Mr-Dh9" firstAttribute="height" secondItem="jPp-7O-HKU" secondAttribute="height" priority="250" id="m6q-fR-N0c"/>
<constraint firstItem="P08-Mr-Dh9" firstAttribute="leading" secondItem="jPp-7O-HKU" secondAttribute="leading" id="tSe-T6-jZs"/>
</constraints>
<nil key="textColor"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<textInputTraits key="textInputTraits"/>
<connections>
<action selector="textFieldEditingChanged:" destination="oms-Lo-Dm1" eventType="editingChanged" id="TJD-V8-zHG"/>
</connections>
</textField>
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Manufacturer Name String" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="VcP-tC-U7U" userLabel="Manufacturer Name Text field">
<rect key="frame" x="16" y="286" width="343" height="35"/>
<constraints>
<constraint firstAttribute="height" constant="35" id="9QA-CU-Rh9"/>
</constraints>
<nil key="textColor"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<textInputTraits key="textInputTraits"/>
<connections>
<action selector="textFieldEditingChanged:" destination="oms-Lo-Dm1" eventType="editingChanged" id="YFU-Tm-wNj"/>
</connections>
</textField>
</scrollView>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="trailing" secondItem="VcP-tC-U7U" secondAttribute="trailing" constant="16" id="E8T-E8-CsT"/>
<constraint firstItem="VcP-tC-U7U" firstAttribute="leading" secondItem="B9k-vm-gSb" secondAttribute="leading" constant="16" id="IhV-It-Fwz"/>
<constraint firstItem="VcP-tC-U7U" firstAttribute="centerY" secondItem="B9k-vm-gSb" secondAttribute="centerY" constant="-30" id="sel-DU-GGv"/>
<constraint firstItem="e8v-xh-WaS" firstAttribute="centerY" secondItem="B9k-vm-gSb" secondAttribute="centerY" constant="30" id="u6U-Zb-zHc"/>
<constraint firstItem="e8v-xh-WaS" firstAttribute="trailing" secondItem="VcP-tC-U7U" secondAttribute="trailing" id="wMN-B8-cII"/>
<constraint firstItem="e8v-xh-WaS" firstAttribute="leading" secondItem="VcP-tC-U7U" secondAttribute="leading" id="x1j-7b-ebk"/>
<constraint firstItem="jPp-7O-HKU" firstAttribute="top" secondItem="7jE-rP-ytQ" secondAttribute="bottom" id="G3K-2N-RTt"/>
<constraint firstItem="jPp-7O-HKU" firstAttribute="leading" secondItem="B9k-vm-gSb" secondAttribute="leading" id="JBi-75-Bnx"/>
<constraint firstItem="zyZ-Rc-zfR" firstAttribute="top" secondItem="jPp-7O-HKU" secondAttribute="bottom" id="bFX-kh-RYm"/>
<constraint firstAttribute="trailing" secondItem="jPp-7O-HKU" secondAttribute="trailing" id="j7J-dK-gmf"/>
</constraints>
</view>
<navigationItem key="navigationItem" title="System ID" id="ghX-3q-eWE"/>
<simulatedNavigationBarMetrics key="simulatedTopBarMetrics" prompted="NO"/>
<connections>
<outlet property="manufacturerIdentifierTextField" destination="VcP-tC-U7U" id="jiv-UU-sfD"/>
<outlet property="organizationallyUniqueIdentifierTextField" destination="e8v-xh-WaS" id="ru8-Ef-eq1"/>
<outlet property="menufacturerIdentifierInputText" destination="hok-5E-9Qf" id="ZRe-Cl-YEh"/>
<outlet property="organizationIdentifierInputText" destination="OAt-PO-DGR" id="bVg-na-5kz"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="2h6-k2-KqZ" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="91.875" y="62.323943661971832"/>
<point key="canvasLocation" x="90.400000000000006" y="61.619190404797607"/>
</scene>
</scenes>
</document>
Loading

0 comments on commit 49e2979

Please sign in to comment.