Support adding otpauth via QR code.

- Check duplicated tokens has not been implimented.
This commit is contained in:
Yishi Lin 2017-04-08 03:08:12 +08:00
parent 405ce459b3
commit 7814a8761e
7 changed files with 300 additions and 67 deletions

View file

@ -12,6 +12,7 @@
A27424D91E7C35960093F436 /* NotificationNames.swift in Sources */ = {isa = PBXBuildFile; fileRef = A27424D81E7C35960093F436 /* NotificationNames.swift */; };
A2802BF91E70813A00879216 /* SliderTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2802BF71E70813A00879216 /* SliderTableViewCell.swift */; };
A2802BFA1E70813A00879216 /* SliderTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = A2802BF81E70813A00879216 /* SliderTableViewCell.xib */; };
A2A7813F1E97DBD9001311F5 /* QRScannerController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2A7813E1E97DBD9001311F5 /* QRScannerController.swift */; };
A2A89D691E954698003FB2D3 /* UITextFieldExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2A89D681E954698003FB2D3 /* UITextFieldExtension.swift */; };
DC037CA61E4B883900609409 /* OpenSourceComponentsTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC037CA51E4B883900609409 /* OpenSourceComponentsTableViewController.swift */; };
DC037CA81E4B898100609409 /* BasicStaticTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC037CA71E4B898100609409 /* BasicStaticTableViewController.swift */; };
@ -85,6 +86,7 @@
A27424D81E7C35960093F436 /* NotificationNames.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NotificationNames.swift; sourceTree = "<group>"; };
A2802BF71E70813A00879216 /* SliderTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SliderTableViewCell.swift; sourceTree = "<group>"; };
A2802BF81E70813A00879216 /* SliderTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = SliderTableViewCell.xib; sourceTree = "<group>"; };
A2A7813E1E97DBD9001311F5 /* QRScannerController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QRScannerController.swift; sourceTree = "<group>"; };
A2A89D681E954698003FB2D3 /* UITextFieldExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UITextFieldExtension.swift; sourceTree = "<group>"; };
ADCE7A5C3CCC67D7D21BB3C4 /* libPods-pass.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-pass.a"; sourceTree = BUILT_PRODUCTS_DIR; };
AEAD6B31EAF5D061447A68CC /* Pods-pass.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-pass.release.xcconfig"; path = "Pods/Target Support Files/Pods-pass/Pods-pass.release.xcconfig"; sourceTree = "<group>"; };
@ -217,6 +219,7 @@
DC037CA91E4B8EAE00609409 /* SpecialThanksTableViewController.swift */,
DC8963BF1E38EEB900828B09 /* SSHKeySettingTableViewController.swift */,
DCC441531E916382008A90C4 /* GitSSHKeyArmorSettingTableViewController.swift */,
A2A7813E1E97DBD9001311F5 /* QRScannerController.swift */,
);
path = Controllers;
sourceTree = "<group>";
@ -381,8 +384,8 @@
};
DC917BD21E2E8231000FDF54 = {
CreatedOnToolsVersion = 8.2.1;
DevelopmentTeam = 4WDM8E95VU;
ProvisioningStyle = Manual;
DevelopmentTeam = FVE7LGR4V3;
ProvisioningStyle = Automatic;
};
};
};
@ -530,6 +533,7 @@
DCFB77A71E502DF9008DE471 /* EditPasswordTableViewController.swift in Sources */,
DCA0499A1E335CC800522E8F /* GitServerSettingTableViewController.swift in Sources */,
DCDDEAB31E4896BF00F68193 /* PasswordDetailTitleTableViewCell.swift in Sources */,
A2A7813F1E97DBD9001311F5 /* QRScannerController.swift in Sources */,
DCC277D21E30D6EA00402246 /* pass.xcdatamodeld in Sources */,
DC4914991E434600007FF592 /* PasswordDetailTableViewController.swift in Sources */,
DC962CDF1E4B62C10033B5D8 /* AboutTableViewController.swift in Sources */,
@ -719,7 +723,7 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CURRENT_PROJECT_VERSION = 2;
DEFINES_MODULE = NO;
DEVELOPMENT_TEAM = 4WDM8E95VU;
DEVELOPMENT_TEAM = FVE7LGR4V3;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Carthage/Build/iOS",
@ -734,10 +738,10 @@
);
INFOPLIST_FILE = pass/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = me.mssun.passforios;
PRODUCT_BUNDLE_IDENTIFIER = rocks.dango.passforios;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "893c10b3-79b1-46f7-914a-e625bf10d665";
PROVISIONING_PROFILE_SPECIFIER = "match Development me.mssun.passforios";
PROVISIONING_PROFILE = "";
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_OBJC_BRIDGING_HEADER = "$(SRCROOT)/pass/Helpers/Objective-CBridgingHeader.h";
SWIFT_VERSION = 3.0;
TARGETED_DEVICE_FAMILY = "1,2";
@ -750,10 +754,10 @@
baseConfigurationReference = AEAD6B31EAF5D061447A68CC /* Pods-pass.release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CURRENT_PROJECT_VERSION = 2;
DEFINES_MODULE = NO;
DEVELOPMENT_TEAM = 4WDM8E95VU;
DEVELOPMENT_TEAM = FVE7LGR4V3;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Carthage/Build/iOS",
@ -768,10 +772,10 @@
);
INFOPLIST_FILE = pass/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = me.mssun.passforios;
PRODUCT_BUNDLE_IDENTIFIER = rocks.dango.passforios;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "aefeea85-1194-4db2-9ce4-fb9995e2fdff";
PROVISIONING_PROFILE_SPECIFIER = "match AppStore me.mssun.passforios";
PROVISIONING_PROFILE = "";
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_OBJC_BRIDGING_HEADER = "$(SRCROOT)/pass/Helpers/Objective-CBridgingHeader.h";
SWIFT_VERSION = 3.0;
TARGETED_DEVICE_FAMILY = "1,2";

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12118" systemVersion="16F43c" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="YoR-iB-XAd">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12118" systemVersion="16E195" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="YoR-iB-XAd">
<device id="retina5_5" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
@ -89,11 +89,11 @@
<rect key="frame" x="0.0" y="35" width="414" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="55g-T3-9ak" id="dKn-cO-EJa">
<rect key="frame" x="0.0" y="0.0" width="381" height="43.666666666666664"/>
<rect key="frame" x="0.0" y="0.0" width="376" height="43.666666666666664"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="General" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="dOt-Rj-vWD">
<rect key="frame" x="15" y="0.0" width="364" height="43.666666666666664"/>
<rect key="frame" x="20" y="0.0" width="356" height="43.666666666666664"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
@ -109,18 +109,18 @@
<rect key="frame" x="0.0" y="79" width="414" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="2rc-ZW-XKd" id="CpT-zb-QEP">
<rect key="frame" x="0.0" y="0.0" width="381" height="43.666666666666664"/>
<rect key="frame" x="0.0" y="0.0" width="376" height="43.666666666666664"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Password Repository" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="gWn-ib-STb">
<rect key="frame" x="15" y="11.999999999999998" width="160.33333333333334" height="20.333333333333332"/>
<rect key="frame" x="20" y="11.999999999999998" width="160.33333333333334" height="20.333333333333332"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Not Set" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Myq-fV-riz">
<rect key="frame" x="321.33333333333331" y="11.999999999999998" width="57.666666666666664" height="20.333333333333332"/>
<rect key="frame" x="318.33333333333331" y="11.999999999999998" width="57.666666666666664" height="20.333333333333332"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.5568627451" green="0.5568627451" blue="0.57647058819999997" alpha="1" colorSpace="calibratedRGB"/>
@ -136,18 +136,18 @@
<rect key="frame" x="0.0" y="123" width="414" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="1ze-MS-Xbj" id="W7U-oL-hOh">
<rect key="frame" x="0.0" y="0.0" width="381" height="43.666666666666664"/>
<rect key="frame" x="0.0" y="0.0" width="376" height="43.666666666666664"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="PGP Key" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="RR9-xr-9ko">
<rect key="frame" x="15" y="11.999999999999998" width="66" height="20.333333333333332"/>
<rect key="frame" x="20" y="11.999999999999998" width="66" height="20.333333333333332"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Not Set" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="7lc-Vh-G9W">
<rect key="frame" x="321.33333333333331" y="11.999999999999998" width="57.666666666666664" height="20.333333333333332"/>
<rect key="frame" x="318.33333333333331" y="11.999999999999998" width="57.666666666666664" height="20.333333333333332"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.55686274509803924" green="0.55686274509803924" blue="0.57647058823529407" alpha="1" colorSpace="calibratedRGB"/>
@ -164,18 +164,18 @@
<rect key="frame" x="0.0" y="223" width="414" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="6Y0-mj-qhA" id="qlv-tQ-Xmc">
<rect key="frame" x="0.0" y="0.0" width="381" height="43.666666666666664"/>
<rect key="frame" x="0.0" y="0.0" width="376" height="43.666666666666664"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Passcode Lock" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="RaZ-6t-0CU">
<rect key="frame" x="15" y="11.999999999999998" width="115" height="20.333333333333332"/>
<rect key="frame" x="20" y="11.999999999999998" width="115" height="20.333333333333332"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Off" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="HXb-ZX-HUv">
<rect key="frame" x="354.66666666666669" y="11.999999999999998" width="24.333333333333332" height="20.333333333333332"/>
<rect key="frame" x="351.66666666666669" y="11.999999999999998" width="24.333333333333332" height="20.333333333333332"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.5568627451" green="0.5568627451" blue="0.57647058819999997" alpha="1" colorSpace="calibratedRGB"/>
@ -192,7 +192,7 @@
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Touch ID" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="H2E-hP-Gyf">
<rect key="frame" x="15" y="0.0" width="384" height="43.666666666666664"/>
<rect key="frame" x="20" y="0.0" width="379" height="43.666666666666664"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
@ -209,11 +209,11 @@
<rect key="frame" x="0.0" y="347" width="414" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="tQN-gu-iRe" id="Xs0-LN-r43">
<rect key="frame" x="0.0" y="0.0" width="381" height="43.666666666666664"/>
<rect key="frame" x="0.0" y="0.0" width="376" height="43.666666666666664"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Advanced" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="MKj-d0-8q3">
<rect key="frame" x="15" y="0.0" width="364" height="43.666666666666664"/>
<rect key="frame" x="20" y="0.0" width="356" height="43.666666666666664"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
@ -233,11 +233,11 @@
<rect key="frame" x="0.0" y="427" width="414" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="osS-xk-WRP" id="G6j-ij-rNr">
<rect key="frame" x="0.0" y="0.0" width="381" height="43.666666666666664"/>
<rect key="frame" x="0.0" y="0.0" width="376" height="43.666666666666664"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="About" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="oqz-Hr-RAl">
<rect key="frame" x="15" y="0.0" width="364" height="43.666666666666664"/>
<rect key="frame" x="20" y="0.0" width="356" height="43.666666666666664"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
@ -288,7 +288,7 @@
<rect key="frame" x="0.0" y="28" width="414" height="54"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" tableViewCell="OfB-1N-1Am" id="fh0-au-C6q">
<rect key="frame" x="0.0" y="0.0" width="414" height="53.5"/>
<rect key="frame" x="0.0" y="0.0" width="414" height="54"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" tag="101" contentMode="left" verticalHuggingPriority="251" preservesSuperviewLayoutMargins="YES" text="2017/04/04" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="GLC-qL-55P">
@ -348,10 +348,10 @@
<tableViewSection headerTitle="Git Repository URL" id="pbe-W6-w4V">
<cells>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="10" reuseIdentifier="gitRepositoryURLTabelViewCell" rowHeight="52" id="FRr-pf-aPO">
<rect key="frame" x="0.0" y="55.5" width="414" height="52"/>
<rect key="frame" x="0.0" y="55" width="414" height="52"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" tableViewCell="FRr-pf-aPO" id="60A-PS-qGe">
<rect key="frame" x="0.0" y="0.0" width="414" height="52"/>
<rect key="frame" x="0.0" y="0.0" width="414" height="51"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Git Repository URL" textAlignment="natural" minimumFontSize="17" clearButtonMode="whileEditing" translatesAutoresizingMaskIntoConstraints="NO" id="EVT-VU-sCi">
@ -378,10 +378,10 @@
<tableViewSection headerTitle="Username" id="fRu-A2-SCk">
<cells>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="10" reuseIdentifier="usernameTableVIewCell" rowHeight="52" id="tnj-5U-kMB">
<rect key="frame" x="0.0" y="163.5" width="414" height="52"/>
<rect key="frame" x="0.0" y="163" width="414" height="52"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" tableViewCell="tnj-5U-kMB" id="f0c-pI-MSJ">
<rect key="frame" x="0.0" y="0.0" width="414" height="52"/>
<rect key="frame" x="0.0" y="0.0" width="414" height="51"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Username" textAlignment="natural" minimumFontSize="17" clearButtonMode="whileEditing" translatesAutoresizingMaskIntoConstraints="NO" id="TMg-Gk-7nG">
@ -407,10 +407,10 @@
<tableViewSection headerTitle="Authentication Method" id="h0N-tI-shZ">
<cells>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="2" indentationWidth="0.0" shouldIndentWhileEditing="NO" id="KrP-nb-haa">
<rect key="frame" x="0.0" y="271.5" width="414" height="44"/>
<rect key="frame" x="0.0" y="271" width="414" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="KrP-nb-haa" id="1uB-oE-kfI">
<rect key="frame" x="0.0" y="0.0" width="414" height="44"/>
<rect key="frame" x="0.0" y="0.0" width="414" height="43"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Password" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="LfQ-Af-j2O">
@ -438,10 +438,10 @@
<inset key="separatorInset" minX="62" minY="0.0" maxX="0.0" maxY="0.0"/>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="blue" accessoryType="detailButton" hidesAccessoryWhenEditing="NO" indentationLevel="2" indentationWidth="0.0" shouldIndentWhileEditing="NO" id="Qmt-bo-CuJ">
<rect key="frame" x="0.0" y="315.5" width="414" height="44"/>
<rect key="frame" x="0.0" y="315" width="414" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="Qmt-bo-CuJ" id="p3u-8b-h3U">
<rect key="frame" x="0.0" y="0.0" width="367" height="44"/>
<rect key="frame" x="0.0" y="0.0" width="367" height="43"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="SSH Key" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Ezz-76-a53">
@ -519,7 +519,7 @@
<rect key="frame" x="0.0" y="35" width="414" height="52"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="BYZ-9g-xZy" id="Zfn-rK-sN1">
<rect key="frame" x="0.0" y="0.0" width="414" height="51.5"/>
<rect key="frame" x="0.0" y="0.0" width="414" height="52"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Public Key URL" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="dWi-eh-7Eq">
@ -553,7 +553,7 @@
<rect key="frame" x="0.0" y="87" width="414" height="52"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="vpk-J8-j7t" id="1td-qT-6ts">
<rect key="frame" x="0.0" y="0.0" width="414" height="51.5"/>
<rect key="frame" x="0.0" y="0.0" width="414" height="52"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Private Key URL" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Qht-RC-Yeg">
@ -639,12 +639,54 @@
</connections>
</barButtonItem>
</navigationItem>
<connections>
<segue destination="A9p-Qb-WmU" kind="show" identifier="showQRScannerSegue" id="mPU-tp-J0X"/>
</connections>
</tableViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="6R0-BP-wo8" userLabel="First Responder" sceneMemberID="firstResponder"/>
<exit id="rRf-7l-IGe" userLabel="Exit" sceneMemberID="exit"/>
</objects>
<point key="canvasLocation" x="4954" y="-1027"/>
</scene>
<!--Scanner-->
<scene sceneID="AuR-rQ-G3V">
<objects>
<viewController id="A9p-Qb-WmU" customClass="QRScannerController" customModule="pass" customModuleProvider="target" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="75M-B3-rK2"/>
<viewControllerLayoutGuide type="bottom" id="eYa-Io-fXF"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="a0T-JY-UcS">
<rect key="frame" x="0.0" y="0.0" width="414" height="736"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="scanner output" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="lOI-p4-BGb">
<rect key="frame" x="50" y="562" width="314" height="45"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="0.5" colorSpace="calibratedRGB"/>
<constraints>
<constraint firstAttribute="height" constant="45" id="bdi-FH-dMP"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstItem="lOI-p4-BGb" firstAttribute="leading" secondItem="a0T-JY-UcS" secondAttribute="leadingMargin" constant="30" id="RCL-aq-Ywc"/>
<constraint firstAttribute="trailingMargin" secondItem="lOI-p4-BGb" secondAttribute="trailing" constant="30" id="qNb-4K-GGl"/>
<constraint firstItem="eYa-Io-fXF" firstAttribute="top" secondItem="lOI-p4-BGb" secondAttribute="bottom" constant="80" id="xl9-X2-aB4"/>
</constraints>
</view>
<navigationItem key="navigationItem" title="Scanner" id="Hlb-5I-bfE"/>
<connections>
<outlet property="scannerOutput" destination="lOI-p4-BGb" id="LZa-eC-1Lc"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="rqh-SR-bIq" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="7088" y="-1008"/>
</scene>
<!--Password Detail Table View Controller-->
<scene sceneID="9wY-d0-fB1">
<objects>
@ -753,6 +795,7 @@
</navigationItem>
<connections>
<segue destination="HB6-Yu-Y3J" kind="unwind" identifier="deletePasswordSegue" unwindAction="deletePasswordWithSegue:" id="L1Z-64-EZh"/>
<segue destination="A9p-Qb-WmU" kind="show" identifier="showQRScannerSegue" id="Cpl-XA-cZ9"/>
</connections>
</tableViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="HlX-6r-eOU" userLabel="First Responder" sceneMemberID="firstResponder"/>
@ -861,7 +904,7 @@
<rect key="frame" x="0.0" y="35" width="414" height="52"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="Jy1-4S-Lvf" id="tJE-ww-okf">
<rect key="frame" x="0.0" y="0.0" width="414" height="51.5"/>
<rect key="frame" x="0.0" y="0.0" width="414" height="52"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Public Key URL" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Oys-xP-ZrB">
@ -895,7 +938,7 @@
<rect key="frame" x="0.0" y="87" width="414" height="52"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="MA5-lE-8dT" id="pTv-Wj-psC">
<rect key="frame" x="0.0" y="0.0" width="414" height="51.5"/>
<rect key="frame" x="0.0" y="0.0" width="414" height="52"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Private Key URL" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="C2w-dd-roS">
@ -1008,7 +1051,7 @@
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Encrypt in ASCII-Armored" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Jwg-mt-woS">
<rect key="frame" x="15" y="0.0" width="384" height="43.666666666666664"/>
<rect key="frame" x="20" y="0.0" width="379" height="43.666666666666664"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
@ -1029,7 +1072,7 @@
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Discard All Local Changes" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="zrl-v3-fxg">
<rect key="frame" x="15" y="0.0" width="384" height="43.666666666666664"/>
<rect key="frame" x="20" y="0.0" width="379" height="43.666666666666664"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.50196081400000003" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
@ -1050,7 +1093,7 @@
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Erase All Password Store Data" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="K2K-Bx-g7Z">
<rect key="frame" x="15" y="0.0" width="384" height="43.666666666666664"/>
<rect key="frame" x="20" y="0.0" width="379" height="43.666666666666664"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.50196081400000003" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
@ -1197,14 +1240,14 @@
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="ASCII-Armor Keys" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="M32-yr-IfE">
<rect key="frame" x="15.000000000000007" y="17" width="121.66666666666667" height="17"/>
<rect key="frame" x="20.000000000000007" y="17" width="121.66666666666667" height="17"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" name="HelveticaNeue-Bold" family="Helvetica Neue" pointSize="14"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" usesAttributedText="YES" lineBreakMode="wordWrap" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="sMx-qd-MTJ">
<rect key="frame" x="15" y="34" width="384" height="119"/>
<rect key="frame" x="20" y="34" width="363.66666666666669" height="119"/>
<autoresizingMask key="autoresizingMask"/>
<attributedString key="attributedText">
<fragment>
@ -1257,7 +1300,7 @@ Cgo
<rect key="frame" x="0.0" y="244" width="414" height="160"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="Lom-iT-l16" id="eya-Tv-r0q">
<rect key="frame" x="0.0" y="0.0" width="414" height="159.5"/>
<rect key="frame" x="0.0" y="0.0" width="414" height="160"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="oyB-oI-1fS">
@ -1284,7 +1327,7 @@ Cgo
<rect key="frame" x="0.0" y="443" width="414" height="160"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="J8U-ev-FRQ" id="eb0-vb-Fcc">
<rect key="frame" x="0.0" y="0.0" width="414" height="159.5"/>
<rect key="frame" x="0.0" y="0.0" width="414" height="160"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="lrQ-Ln-ZOv">
@ -1389,14 +1432,14 @@ Cgo
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="ASCII-Armor Keys" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="i78-t7-fP9">
<rect key="frame" x="15.000000000000007" y="37" width="121.66666666666667" height="17"/>
<rect key="frame" x="20.000000000000007" y="37" width="121.66666666666667" height="17"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" name="HelveticaNeue-Bold" family="Helvetica Neue" pointSize="14"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" usesAttributedText="YES" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Oit-sd-wa5">
<rect key="frame" x="15" y="53.999999999999993" width="344" height="79.333333333333329"/>
<rect key="frame" x="20" y="53.999999999999993" width="344" height="79.333333333333329"/>
<autoresizingMask key="autoresizingMask"/>
<attributedString key="attributedText">
<fragment>
@ -1432,7 +1475,7 @@ Cgo
<rect key="frame" x="0.0" y="244" width="414" height="160"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="3po-uS-Nch" id="pet-if-EHU">
<rect key="frame" x="0.0" y="0.0" width="414" height="159.5"/>
<rect key="frame" x="0.0" y="0.0" width="414" height="160"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Y9t-DD-6uH">
@ -1459,7 +1502,7 @@ Cgo
<rect key="frame" x="0.0" y="443" width="414" height="160"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="nmc-vy-Ab5" id="TQD-GC-YOY">
<rect key="frame" x="0.0" y="0.0" width="414" height="159.5"/>
<rect key="frame" x="0.0" y="0.0" width="414" height="160"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="23o-MP-wQY">
@ -1507,4 +1550,7 @@ Cgo
<image name="Lock" width="25" height="25"/>
<image name="Settings" width="25" height="25"/>
</resources>
<inferredMetricsTieBreakers>
<segue reference="Cpl-XA-cZ9"/>
</inferredMetricsTieBreakers>
</document>

View file

@ -19,6 +19,7 @@ class AddPasswordTableViewController: PasswordEditorTableViewController {
[[.type: PasswordEditorCellType.fillPasswordCell, .title: "password"],
[.type: PasswordEditorCellType.passwordLengthCell, .title: "passwordlength"]],
[[.type: PasswordEditorCellType.textViewCell, .title: "additions"]],
[[.type: PasswordEditorCellType.scanQRCodeCell]]
]
super.viewDidLoad()
}
@ -54,13 +55,15 @@ class AddPasswordTableViewController: PasswordEditorTableViewController {
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "saveAddPasswordSegue" {let cells = tableView.visibleCells
super.prepare(for: segue, sender: sender)
if segue.identifier == "saveAddPasswordSegue" {
let cells = tableView.visibleCells
var cellContents = [String: String]()
for cell in cells {
let indexPath = tableView.indexPath(for: cell)!
let contentCell = cell as! ContentTableViewCell
let cellTitle = tableData[indexPath.section][indexPath.row][.title] as! String
if let cellContent = contentCell.getContent() {
if let indexPath = tableView.indexPath(for: cell),
let contentCell = cell as? ContentTableViewCell,
let cellTitle = tableData[indexPath.section][indexPath.row][.title] as? String,
let cellContent = contentCell.getContent() {
cellContents[cellTitle] = cellContent
}
}

View file

@ -15,7 +15,8 @@ class EditPasswordTableViewController: PasswordEditorTableViewController {
[[.type: PasswordEditorCellType.fillPasswordCell, .title: "password", .content: password!.password],
[.type: PasswordEditorCellType.passwordLengthCell, .title: "passwordlength"]],
[[.type: PasswordEditorCellType.textViewCell, .title: "additions", .content: password!.getAdditionsPlainText()]],
[[.type: PasswordEditorCellType.deletePasswordCell]],
[[.type: PasswordEditorCellType.scanQRCodeCell],
[.type: PasswordEditorCellType.deletePasswordCell]]
]
super.viewDidLoad()
}
@ -37,16 +38,16 @@ class EditPasswordTableViewController: PasswordEditorTableViewController {
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
super.prepare(for: segue, sender: sender)
if segue.identifier == "saveEditPasswordSegue" {
let cells = tableView.visibleCells
var cellContents = [String: String]()
for cell in cells {
let indexPath = tableView.indexPath(for: cell)!
if let contentCell = cell as? ContentTableViewCell {
let cellTitle = tableData[indexPath.section][indexPath.row][.title] as! String
if let cellContent = contentCell.getContent() {
cellContents[cellTitle] = cellContent
}
if let indexPath = tableView.indexPath(for: cell),
let contentCell = cell as? ContentTableViewCell,
let cellTitle = tableData[indexPath.section][indexPath.row][.title] as? String,
let cellContent = contentCell.getContent() {
cellContents[cellTitle] = cellContent
}
}
var plainText = ""

View file

@ -8,16 +8,17 @@
import UIKit
import SwiftyUserDefaults
import OneTimePassword
enum PasswordEditorCellType {
case textFieldCell, textViewCell, fillPasswordCell, passwordLengthCell, deletePasswordCell
case textFieldCell, textViewCell, fillPasswordCell, passwordLengthCell, deletePasswordCell, scanQRCodeCell
}
enum PasswordEditorCellKey {
case type, title, content, placeholders
}
class PasswordEditorTableViewController: UITableViewController, FillPasswordTableViewCellDelegate, PasswordSettingSliderTableViewCellDelegate, UIGestureRecognizerDelegate {
class PasswordEditorTableViewController: UITableViewController, FillPasswordTableViewCellDelegate, PasswordSettingSliderTableViewCellDelegate, QRScannerControllerDelegate {
var tableData = [
[Dictionary<PasswordEditorCellKey, Any>]
@ -29,11 +30,13 @@ class PasswordEditorTableViewController: UITableViewController, FillPasswordTabl
private var sectionHeaderTitles = ["name", "password", "additions",""].map {$0.uppercased()}
private var sectionFooterTitles = ["", "", "Use \"key: value\" format for additional fields.", ""]
private let passwordSection = 1
private let additionsSection = 2
private var hidePasswordSettings = true
private var fillPasswordCell: FillPasswordTableViewCell?
private var passwordLengthCell: SliderTableViewCell?
private var deletePasswordCell: UITableViewCell?
private var scanQRCodeCell: UITableViewCell?
override func loadView() {
super.loadView()
@ -42,6 +45,14 @@ class PasswordEditorTableViewController: UITableViewController, FillPasswordTabl
deletePasswordCell!.textLabel?.text = "Delete Password"
deletePasswordCell!.textLabel?.textColor = Globals.red
deletePasswordCell?.selectionStyle = .default
scanQRCodeCell = UITableViewCell(style: .default, reuseIdentifier: "default")
scanQRCodeCell?.textLabel?.text = "Add One-Time Password"
scanQRCodeCell?.textLabel?.textColor = Globals.blue
scanQRCodeCell?.selectionStyle = .default
// scanQRCodeCell?.imageView?.image = #imageLiteral(resourceName: "Camera").withRenderingMode(.alwaysTemplate)
// scanQRCodeCell?.imageView?.tintColor = Globals.blue
// scanQRCodeCell?.imageView?.contentMode = .scaleAspectFit
}
override func viewDidLoad() {
@ -86,6 +97,8 @@ class PasswordEditorTableViewController: UITableViewController, FillPasswordTabl
return passwordLengthCell!
case .deletePasswordCell:
return deletePasswordCell!
case .scanQRCodeCell:
return scanQRCodeCell!
default:
let cell = tableView.dequeueReusableCell(withIdentifier: "textFieldCell", for: indexPath) as! ContentTableViewCell
cell.setContent(content: cellData[PasswordEditorCellKey.content] as? String)
@ -119,13 +132,16 @@ class PasswordEditorTableViewController: UITableViewController, FillPasswordTabl
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if tableView.cellForRow(at: indexPath) == deletePasswordCell {
let selectedCell = tableView.cellForRow(at: indexPath)
if selectedCell == deletePasswordCell {
let alert = UIAlertController(title: "Delete Password?", message: nil, preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "Delete", style: UIAlertActionStyle.destructive, handler: {[unowned self] (action) -> Void in
self.performSegue(withIdentifier: "deletePasswordSegue", sender: self)
}))
alert.addAction(UIAlertAction(title: "Cancel", style: UIAlertActionStyle.cancel, handler:nil))
self.present(alert, animated: true, completion: nil)
} else if selectedCell == scanQRCodeCell {
self.performSegue(withIdentifier: "showQRScannerSegue", sender: self)
}
tableView.deselectRow(at: indexPath, animated: true)
}
@ -168,4 +184,37 @@ class PasswordEditorTableViewController: UITableViewController, FillPasswordTabl
hidePasswordSettings = !hidePasswordSettings
tableView.reloadSections([passwordSection], with: .fade)
}
func insertScannedOTPFields(_ otpauth: String) {
// update tableData
if let additionsPlainText = (tableData[additionsSection][0][PasswordEditorCellKey.content] as? String)?.trimmingCharacters(in: .whitespacesAndNewlines), additionsPlainText != "" {
tableData[additionsSection][0][PasswordEditorCellKey.content] = additionsPlainText + "\n" + otpauth
} else {
tableData[additionsSection][0][PasswordEditorCellKey.content] = otpauth
}
// reload
tableView.reloadSections([additionsSection], with: .none)
}
// MARK: - QRScannerControllerDelegate Methods
func checkScannedOutput(line: String) -> (accept: Bool, message: String) {
if let url = URL(string: line), let _ = Token(url: url) {
return (accept: true, message: "Valid token URL")
} else {
return (accept: false, message: "Invalid token URL")
}
}
// MARK: - QRScannerControllerDelegate Methods
func handleScannedOutput(line: String) {
insertScannedOTPFields(line)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showQRScannerSegue" {
if let viewController = segue.destination as? QRScannerController {
viewController.delegate = self
}
}
}
}

View file

@ -0,0 +1,128 @@
//
// QRScannerController.swift
// pass
//
// Created by Yishi Lin on 7/4/17.
// Copyright © 2017 Yishi Lin. All rights reserved.
//
import UIKit
import AVFoundation
import OneTimePassword
import SVProgressHUD
protocol QRScannerControllerDelegate {
func checkScannedOutput(line: String) -> (accept: Bool, message: String)
func handleScannedOutput(line: String)
}
class QRScannerController: UIViewController, AVCaptureMetadataOutputObjectsDelegate {
@IBOutlet weak var scannerOutput: UILabel!
var captureSession: AVCaptureSession?
var videoPreviewLayer: AVCaptureVideoPreviewLayer?
var qrCodeFrameView: UIView?
let supportedCodeTypes = [AVMetadataObjectTypeQRCode]
var delegate: QRScannerControllerDelegate?
override func viewDidLoad() {
super.viewDidLoad()
// Get an instance of the AVCaptureDevice class to initialize a device object and provide the video as the media type parameter.
let captureDevice = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo)
do {
// Get an instance of the AVCaptureDeviceInput class using the previous device object.
let input = try AVCaptureDeviceInput(device: captureDevice)
// Initialize the captureSession object.
captureSession = AVCaptureSession()
// Set the input device on the capture session.
captureSession?.addInput(input)
// Initialize a AVCaptureMetadataOutput object and set it as the output device to the capture session.
let captureMetadataOutput = AVCaptureMetadataOutput()
captureSession?.addOutput(captureMetadataOutput)
// Set delegate and use the default dispatch queue to execute the call back
captureMetadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
captureMetadataOutput.metadataObjectTypes = supportedCodeTypes
// Initialize the video preview layer and add it as a sublayer to the viewPreview view's layer.
videoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
videoPreviewLayer?.videoGravity = AVLayerVideoGravityResizeAspectFill
videoPreviewLayer?.frame = view.layer.bounds
view.layer.addSublayer(videoPreviewLayer!)
// Start video capture.
captureSession?.startRunning()
// Move the message label to the front
scannerOutput.layer.cornerRadius = 10
scannerOutput.text = "No QR code detected"
view.bringSubview(toFront: scannerOutput)
// Initialize QR Code Frame to highlight the QR code
qrCodeFrameView = UIView()
if let qrCodeFrameView = qrCodeFrameView {
qrCodeFrameView.layer.borderColor = UIColor.green.cgColor
qrCodeFrameView.layer.borderWidth = 2
view.addSubview(qrCodeFrameView)
view.bringSubview(toFront: qrCodeFrameView)
}
} catch {
print(error)
return
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - AVCaptureMetadataOutputObjectsDelegate Methods
func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [Any]!, from connection: AVCaptureConnection!) {
if let metadataObj = metadataObjects.first as? AVMetadataMachineReadableCodeObject,
supportedCodeTypes.contains(metadataObj.type),
let barCodeObject = videoPreviewLayer?.transformedMetadataObject(for: metadataObj) {
// draw a bounds on the found QR code
qrCodeFrameView?.frame = barCodeObject.bounds
// check whether it is a valid result
if let scanned = metadataObj.stringValue {
if let (accept, message) = delegate?.checkScannedOutput(line: scanned) {
scannerOutput.text = message
if accept == true {
captureSession?.stopRunning()
delegate?.handleScannedOutput(line: scanned)
DispatchQueue.main.async {
SVProgressHUD.showSuccess(withStatus: "Done")
SVProgressHUD.dismiss(withDelay: 1)
self.navigationController?.popViewController(animated: true)
}
}
} else {
// no delegate, show the scanned result
scannerOutput.text = scanned
}
} else {
scannerOutput.text = "No string value"
}
} else {
qrCodeFrameView?.frame = CGRect.zero
scannerOutput.text = "No QR code detected"
}
}
}

View file

@ -24,6 +24,8 @@
<false/>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSCameraUsageDescription</key>
<string>We need to access your camera for scanning QR code.</string>
<key>UIApplicationShortcutItems</key>
<array>
<dict>