Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ xcuserdata/
## Other
*.moved-aside
*.xcuserstate
.vscode

## Obj-C/Swift specific
*.hmap
Expand Down Expand Up @@ -63,4 +64,4 @@ fastlane/report.xml
fastlane/Preview.html
fastlane/screenshots
fastlane/test_output
docs/
docs/
9 changes: 1 addition & 8 deletions Cely Demo/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {

func application(_: UIApplication, didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
Cely.setup(with: window!, forModel: User(), requiredProperties: [.token], withOptions: [
.loginCompletionBlock: { (username: String, password: String) in
if username == "asdf", password == "asdf" {
if User.save("FAKETOKEN:\(username)\(password)", as: .token) == .success {
Cely.changeStatus(to: .loggedIn)
}
}
},
.celyAnimator: CustomAnimator(),
.loginViewController: UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "BiometricLoginViewController"),
])

return true
Expand Down
109 changes: 100 additions & 9 deletions Cely Demo/Base.lproj/Main.storyboard
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="svJ-It-h7B">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14868" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="svJ-It-h7B">
<device id="retina4_7" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14490.49"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14824"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
Expand All @@ -22,7 +20,7 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="yRN-nu-lVm">
<rect key="frame" x="16" y="20" width="57" height="30"/>
<rect key="frame" x="16" y="0.0" width="57" height="30"/>
<state key="normal" title="Settings">
<color key="titleColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
</state>
Expand Down Expand Up @@ -51,22 +49,33 @@
<viewControllerLayoutGuide type="bottom" id="FXo-zn-Apn"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="Zq6-aU-iAv">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="647"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="7CJ-Uc-HQ6">
<rect key="frame" x="163.5" y="318.5" width="48" height="30"/>
<rect key="frame" x="163.5" y="308.5" width="48" height="30"/>
<state key="normal" title="Logout">
<color key="titleColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
</state>
<connections>
<action selector="LogoutButtonPressed" destination="rRA-t9-7xr" eventType="touchUpInside" id="80u-8N-Lcf"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="3U4-et-wir">
<rect key="frame" x="134" y="215" width="107" height="30"/>
<state key="normal" title="Get Credentials">
<color key="titleColor" systemColor="linkColor" red="0.0" green="0.47843137254901963" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<connections>
<action selector="getCredentialsClicked:" destination="rRA-t9-7xr" eventType="touchUpInside" id="eKB-Ky-FV9"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" red="0.86666667460000002" green="0.57254904510000004" blue="0.12549020350000001" alpha="1" colorSpace="calibratedRGB"/>
<constraints>
<constraint firstItem="3U4-et-wir" firstAttribute="centerX" secondItem="7CJ-Uc-HQ6" secondAttribute="centerX" id="F3o-4N-SDZ"/>
<constraint firstItem="7CJ-Uc-HQ6" firstAttribute="centerY" secondItem="Zq6-aU-iAv" secondAttribute="centerY" id="GMB-Tl-mG3"/>
<constraint firstItem="7CJ-Uc-HQ6" firstAttribute="top" secondItem="3U4-et-wir" secondAttribute="bottom" constant="63.5" id="W06-ee-gKi"/>
<constraint firstItem="7CJ-Uc-HQ6" firstAttribute="centerX" secondItem="Zq6-aU-iAv" secondAttribute="centerX" id="rim-CG-HdC"/>
</constraints>
</view>
Expand All @@ -88,7 +97,7 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="OjC-PT-mCd">
<rect key="frame" x="16" y="20" width="57" height="30"/>
<rect key="frame" x="16" y="0.0" width="57" height="30"/>
<state key="normal" title="Settings">
<color key="titleColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
</state>
Expand All @@ -105,5 +114,87 @@
</objects>
<point key="canvasLocation" x="-204" y="743"/>
</scene>
<!--Biometric Login View Controller-->
<scene sceneID="YN1-YY-izx">
<objects>
<viewController storyboardIdentifier="BiometricLoginViewController" id="ZP6-Re-yGd" customClass="BiometricLoginViewController" customModule="Cely_Demo" customModuleProvider="target" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="g3F-RX-NbP"/>
<viewControllerLayoutGuide type="bottom" id="be8-I8-7fR"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="wmf-O2-iNa">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="20" translatesAutoresizingMaskIntoConstraints="NO" id="2oj-QE-1Z6">
<rect key="frame" x="20" y="297" width="335" height="150"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="10" translatesAutoresizingMaskIntoConstraints="NO" id="nbc-pp-i8c">
<rect key="frame" x="0.0" y="0.0" width="335" height="90"/>
<subviews>
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Username" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="OTm-Xc-nHh">
<rect key="frame" x="0.0" y="0.0" width="335" height="40"/>
<color key="backgroundColor" white="1" alpha="0.40019415679999998" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstAttribute="height" constant="40" id="a7M-GG-JoO"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<textInputTraits key="textInputTraits" autocorrectionType="no" spellCheckingType="no"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="leftSpacer">
<real key="value" value="20"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</textField>
<textField opaque="NO" clipsSubviews="YES" tag="1" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Password" clearsOnBeginEditing="YES" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="8gJ-ra-7hL">
<rect key="frame" x="0.0" y="50" width="335" height="40"/>
<color key="backgroundColor" white="1" alpha="0.40000000000000002" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstAttribute="height" constant="40" id="ZIl-36-v79"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<textInputTraits key="textInputTraits" secureTextEntry="YES"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="leftSpacer">
<real key="value" value="20"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</textField>
</subviews>
</stackView>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="4XI-If-mOR">
<rect key="frame" x="0.0" y="110" width="335" height="40"/>
<color key="backgroundColor" red="0.33725490200000002" green="0.79607843140000001" blue="0.97647058819999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="height" constant="40" id="fg4-L0-LYw"/>
</constraints>
<state key="normal" title="Login">
<color key="titleColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<connections>
<action selector="loginButtonPressed" destination="ZP6-Re-yGd" eventType="touchUpInside" id="jcg-w4-8dR"/>
</connections>
</button>
</subviews>
</stackView>
</subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<constraints>
<constraint firstItem="2oj-QE-1Z6" firstAttribute="centerX" secondItem="wmf-O2-iNa" secondAttribute="centerX" id="4qo-2o-MUF"/>
<constraint firstItem="be8-I8-7fR" firstAttribute="top" secondItem="2oj-QE-1Z6" secondAttribute="bottom" constant="220" id="YI2-k1-LZs"/>
<constraint firstItem="2oj-QE-1Z6" firstAttribute="leading" secondItem="wmf-O2-iNa" secondAttribute="leading" constant="20" id="d3l-qa-RPr"/>
</constraints>
</view>
<connections>
<outlet property="passwordField" destination="8gJ-ra-7hL" id="pol-F4-ncb"/>
<outlet property="usernameField" destination="OTm-Xc-nHh" id="CBV-pa-W9H"/>
<outletCollection property="textFields" destination="OTm-Xc-nHh" collectionClass="NSMutableArray" id="gR0-UN-A0f"/>
<outletCollection property="textFields" destination="8gJ-ra-7hL" collectionClass="NSMutableArray" id="L4x-Ls-2Kc"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="DJp-Xq-4uv" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="788" y="743"/>
</scene>
</scenes>
</document>
74 changes: 74 additions & 0 deletions Cely Demo/BiometricLoginViewController.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
//
// BiometricLoginViewController.swift
// Cely Demo
//
// Created by Fabian Buentello on 10/5/19.
// Copyright © 2019 Fabian Buentello. All rights reserved.
//

import Cely
import UIKit

class BiometricLoginViewController: UIViewController, UITextFieldDelegate {
@IBOutlet weak var usernameField: UITextField?
@IBOutlet weak var passwordField: UITextField?

@IBOutlet var textFields: [UITextField]?

var credentialsExist = false

override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let credentialsResult = Cely.credentials.get()
if case let .success(creds) = credentialsResult {
print(creds)
credentialsExist = true
usernameField?.text = creds.username
passwordField?.text = creds.password
loginButtonPressed()
}
}

override func viewDidLoad() {
super.viewDidLoad()

usernameField?.delegate = self
passwordField?.delegate = self
}

@IBAction func loginButtonPressed() {
if let username = usernameField?.text, let password = passwordField?.text {
let tokenResult = User.save("FAKETOKEN:\(username)\(password)", as: .token)
if case let .failure(error) = tokenResult {
return print("tokenResult Error: \(error)")
}

if !credentialsExist {
let credentialResult = Cely.credentials.set(
username: username,
password: password,
server: "api.example.com",
options: [.biometricsIfPossible]
)

if case let .failure(error) = credentialResult {
return print("Cely store credentials error: \(error)")
}
}

Cely.changeStatus(to: .loggedIn)
}
}

func textFieldShouldReturn(_ textField: UITextField) -> Bool {
let nextTag = textField.tag + 1

if let next = textFields?.filter({ $0.tag == nextTag }).first {
next.becomeFirstResponder()
return true
}

textField.resignFirstResponder()
return true
}
}
7 changes: 1 addition & 6 deletions Cely Demo/Cely Demo.entitlements
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>keychain-access-groups</key>
<array>
<string>$(AppIdentifierPrefix)com.cely.Cely-Demo</string>
</array>
</dict>
<dict/>
</plist>
2 changes: 2 additions & 0 deletions Cely Demo/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSFaceIDUsageDescription</key>
<string>Cely Demo</string>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
Expand Down
11 changes: 11 additions & 0 deletions Cely Demo/LoginStyles.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,17 @@ struct LoginStyles: CelyStyle {
}
}

extension UIWindow {
func setCurrentViewController(to viewController: UIViewController?) {
let previousViewController = rootViewController
rootViewController = viewController

if let previousViewController = previousViewController {
previousViewController.dismiss(animated: false)
}
}
}

struct CustomAnimator: CelyAnimator {
func loginTransition(to destinationVC: UIViewController?, with celyWindow: UIWindow) {
guard let snapshot = celyWindow.snapshotView(afterScreenUpdates: true) else {
Expand Down
16 changes: 15 additions & 1 deletion Cely Demo/SettingsViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,20 @@ import UIKit

class SettingsViewController: UIViewController {
@IBAction func LogoutButtonPressed() {
Cely.logout()
let result = Cely.logout()
if case let .failure(error) = result {
print(error)
}
}

@IBAction func getCredentialsClicked(_: Any) {
let result = Cely.credentials.get()
switch result {
case let .success(credentials):
print(credentials)
case let .failure(error):
print("failed to get credentials")
print(error)
}
}
}
4 changes: 2 additions & 2 deletions Cely Demo/User.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ struct User: CelyUser {
}
}

@discardableResult func save(_ value: Any) -> StorageResult {
@discardableResult func save(_ value: Any) -> Result<Void, Error> {
return Cely.save(value, forKey: rawValue, securely: securely(), persisted: persisted())
}

Expand All @@ -46,7 +46,7 @@ struct User: CelyUser {
// MARK: - Save/Get User Properties

extension User {
@discardableResult static func save(_ value: Any, as property: Property) -> StorageResult {
@discardableResult static func save(_ value: Any, as property: Property) -> Result<Void, Error> {
return property.save(value)
}

Expand Down
Loading