Skip to content

Commit

Permalink
Added CountryTableViewController
Browse files Browse the repository at this point in the history
Added Country DataStore
Added Country Data Resource
  • Loading branch information
cocojoe committed Apr 7, 2017
1 parent 6ff6f0a commit ac3a21f
Show file tree
Hide file tree
Showing 17 changed files with 424 additions and 347 deletions.
2 changes: 1 addition & 1 deletion Lock.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Auth0 is a SaaS that helps you with Authentication and Authorization. You can us

s.subspec 'Classic' do |classic|
classic.ios.source_files = "Lock/**/*.swift"
classic.ios.resource = ["Lock/*.xcassets", "Lock/*.lproj"]
classic.ios.resource = ["Lock/*.xcassets", "Lock/*.lproj", "Lock/*.json"]
end

end
28 changes: 20 additions & 8 deletions Lock.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@
5B2826431E32297E00E48467 /* NativeHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B2826421E32297E00E48467 /* NativeHandler.swift */; };
5B2981781DD51A460062535C /* InfoBarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B2981771DD51A460062535C /* InfoBarView.swift */; };
5B3440C11E7C0955009F8BF7 /* Navigable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B3440C01E7C0955009F8BF7 /* Navigable.swift */; };
5B3DA2531E6DE88900370C17 /* InternationalPhoneInputView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B3DA2521E6DE88900370C17 /* InternationalPhoneInputView.swift */; };
5B3440C31E7C0987009F8BF7 /* ClassicRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B3440C21E7C0987009F8BF7 /* ClassicRouter.swift */; };
5B3440C51E7C09A1009F8BF7 /* PasswordlessRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B3440C41E7C09A1009F8BF7 /* PasswordlessRouter.swift */; };
5B3DA2531E6DE88900370C17 /* CountrySelectorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B3DA2521E6DE88900370C17 /* CountrySelectorView.swift */; };
5B3DA2551E6EB9F800370C17 /* TableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B3DA2541E6EB9F800370C17 /* TableViewController.swift */; };
5B3DA2551E6EB9F800370C17 /* CountryTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B3DA2541E6EB9F800370C17 /* CountryTableViewController.swift */; };
5B4177431E44827B007843EA /* Auth0OAuth2InteractorSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F92C68A1D4FE90F00CCE6C0 /* Auth0OAuth2InteractorSpec.swift */; };
5B3440CB1E7C11E7009F8BF7 /* ClassicRouterSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B3440C91E7C11E5009F8BF7 /* ClassicRouterSpec.swift */; };
5B3440CC1E7C11EB009F8BF7 /* PasswordlessRouterSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B3440C61E7C0D6E009F8BF7 /* PasswordlessRouterSpec.swift */; };
Expand All @@ -42,6 +42,9 @@
5B568F821E4B6506004B3D98 /* PasswordlessAuthenticatableError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B568F811E4B6506004B3D98 /* PasswordlessAuthenticatableError.swift */; };
5B5F9F9F1E4B3FBE00EAB9EE /* PasswordlessView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B5F9F9E1E4B3FBE00EAB9EE /* PasswordlessView.swift */; };
5B6631531DDB9B28001CB043 /* EnterpriseDomainInteractorSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B6631511DDB990B001CB043 /* EnterpriseDomainInteractorSpec.swift */; };
5B889AEE1E700FCA00C9FBAF /* CountryCodeStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B889AED1E700FCA00C9FBAF /* CountryCodeStore.swift */; };
5B889AF01E7022B900C9FBAF /* ControllerModalPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B889AEF1E7022B900C9FBAF /* ControllerModalPresenter.swift */; };
5B889AF21E704F4600C9FBAF /* passwordless_sms_countries.json in Resources */ = {isa = PBXBuildFile; fileRef = 5B889AF11E704F4600C9FBAF /* passwordless_sms_countries.json */; };
5B9A54441E4B275E004B5454 /* PasswordlessInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B9A54431E4B275E004B5454 /* PasswordlessInteractor.swift */; };
5B9A54461E4B2CB4004B5454 /* PasswordlessAuthenticatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B9A54451E4B2CB4004B5454 /* PasswordlessAuthenticatable.swift */; };
5B9A544A1E4B354A004B5454 /* PasswordlessPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B9A54491E4B354A004B5454 /* PasswordlessPresenter.swift */; };
Expand Down Expand Up @@ -231,8 +234,8 @@
5B1FD9711E546F500055C1AC /* PasswordlessInteractorSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PasswordlessInteractorSpec.swift; sourceTree = "<group>"; };
5B2826421E32297E00E48467 /* NativeHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NativeHandler.swift; sourceTree = "<group>"; };
5B2981771DD51A460062535C /* InfoBarView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = InfoBarView.swift; path = Lock/InfoBarView.swift; sourceTree = SOURCE_ROOT; };
5B3DA2521E6DE88900370C17 /* CountrySelectorView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CountrySelectorView.swift; sourceTree = "<group>"; };
5B3DA2541E6EB9F800370C17 /* TableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TableViewController.swift; sourceTree = "<group>"; };
5B3DA2521E6DE88900370C17 /* InternationalPhoneInputView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InternationalPhoneInputView.swift; sourceTree = "<group>"; };
5B3DA2541E6EB9F800370C17 /* CountryTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CountryTableViewController.swift; sourceTree = "<group>"; };
5B3440C01E7C0955009F8BF7 /* Navigable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Navigable.swift; sourceTree = "<group>"; };
5B3440C21E7C0987009F8BF7 /* ClassicRouter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ClassicRouter.swift; sourceTree = "<group>"; };
5B3440C41E7C09A1009F8BF7 /* PasswordlessRouter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PasswordlessRouter.swift; sourceTree = "<group>"; };
Expand All @@ -250,6 +253,9 @@
5B568F811E4B6506004B3D98 /* PasswordlessAuthenticatableError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PasswordlessAuthenticatableError.swift; sourceTree = "<group>"; };
5B5F9F9E1E4B3FBE00EAB9EE /* PasswordlessView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PasswordlessView.swift; sourceTree = "<group>"; };
5B6631511DDB990B001CB043 /* EnterpriseDomainInteractorSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EnterpriseDomainInteractorSpec.swift; sourceTree = "<group>"; };
5B889AED1E700FCA00C9FBAF /* CountryCodeStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CountryCodeStore.swift; sourceTree = "<group>"; };
5B889AEF1E7022B900C9FBAF /* ControllerModalPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ControllerModalPresenter.swift; sourceTree = "<group>"; };
5B889AF11E704F4600C9FBAF /* passwordless_sms_countries.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = passwordless_sms_countries.json; sourceTree = "<group>"; };
5B9A54431E4B275E004B5454 /* PasswordlessInteractor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PasswordlessInteractor.swift; sourceTree = "<group>"; };
5B9A54451E4B2CB4004B5454 /* PasswordlessAuthenticatable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PasswordlessAuthenticatable.swift; sourceTree = "<group>"; };
5B9A54491E4B354A004B5454 /* PasswordlessPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PasswordlessPresenter.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -570,6 +576,7 @@
5F70F1EC1D790A6D004698DA /* Supporting Files */ = {
isa = PBXGroup;
children = (
5B889AF11E704F4600C9FBAF /* passwordless_sms_countries.json */,
5FEAE1CB1D1A5154005C0028 /* Info.plist */,
5FEAE1C91D1A5154005C0028 /* Lock.h */,
5F99AA791D1B031500D27842 /* Lock.xcassets */,
Expand Down Expand Up @@ -597,6 +604,7 @@
5FDC876C1D46DAF200D28596 /* Queue.swift */,
5F92C68E1D50EAC200CCE6C0 /* LazyImage.swift */,
5F1456591D5130E80085DF9C /* Colors.swift */,
5B889AEF1E7022B900C9FBAF /* ControllerModalPresenter.swift */,
5F390E861D638A6D00FC549C /* Logger.swift */,
5FF0B2271E1726C400A73257 /* CredentialAuth.swift */,
5B1FD96C1E4E2B6B0055C1AC /* PasswordlessActivity.swift */,
Expand All @@ -614,6 +622,7 @@
5B2826421E32297E00E48467 /* NativeHandler.swift */,
5B568F7F1E4B64D2004B3D98 /* Passwordless.swift */,
5FBE5CB71D3D8F030038536D /* User.swift */,
5B889AED1E700FCA00C9FBAF /* CountryCodeStore.swift */,
5F57DFC51D4F79DD00C54DA8 /* AuthStyle.swift */,
5F1C498D1D8360AA005B74FC /* Style.swift */,
5F70F1EA1D7909C4004698DA /* Connections */,
Expand Down Expand Up @@ -745,15 +754,15 @@
5FC4348B1D1DFC5A005188BC /* Form.swift */,
5FEAE20F1D1A5691005C0028 /* HeaderView.swift */,
5F99AA8B1D1B3F1300D27842 /* InputField.swift */,
5B3DA2521E6DE88900370C17 /* CountrySelectorView.swift */,
5FDB41CF1D2C95B100166B67 /* MessageView.swift */,
5F99AA891D1B360C00D27842 /* PrimaryButton.swift */,
5F99AA931D1BABFC00D27842 /* SecondaryButton.swift */,
5F51EE671D1C88FC0024BCD6 /* SignUpView.swift */,
5F51EE691D1CBC830024BCD6 /* SingleInputView.swift */,
5FD6772B1D4C303C004B87C4 /* AuthButton.swift */,
5F5D4A251DC3FB34002A38EB /* PasswordPolicyView.swift */,
5B3DA2541E6EB9F800370C17 /* TableViewController.swift */,
5B3DA2521E6DE88900370C17 /* InternationalPhoneInputView.swift */,
5B3DA2541E6EB9F800370C17 /* CountryTableViewController.swift */,
);
name = Components;
path = Lock;
Expand Down Expand Up @@ -945,6 +954,7 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
5B889AF21E704F4600C9FBAF /* passwordless_sms_countries.json in Resources */,
5F99AA7A1D1B031500D27842 /* Lock.xcassets in Resources */,
5FF45EA81E549EA2008224C8 /* Lock.strings in Resources */,
);
Expand Down Expand Up @@ -1043,7 +1053,7 @@
5FF0B2281E1726C400A73257 /* CredentialAuth.swift in Sources */,
5F99AA861D1B0BF100D27842 /* Resources.swift in Sources */,
5F2496B81D665AC500A1C6E2 /* UserAttribute.swift in Sources */,
5B3DA2551E6EB9F800370C17 /* TableViewController.swift in Sources */,
5B3DA2551E6EB9F800370C17 /* CountryTableViewController.swift in Sources */,
5F70F1DF1D7904A3004698DA /* ConnectionBuildable.swift in Sources */,
5FC4348F1D1E0A57005188BC /* DatabaseAuthenticable.swift in Sources */,
5BE4344F1E64820800950FA1 /* PasswordRecoverable.swift in Sources */,
Expand All @@ -1063,6 +1073,7 @@
5B0971801DC8F5C4003AA88F /* EnterpriseDomainPresenter.swift in Sources */,
5FC434861D1DF769005188BC /* View.swift in Sources */,
5FDB41CE1D2C79FD00166B67 /* Operations.swift in Sources */,
5B889AEE1E700FCA00C9FBAF /* CountryCodeStore.swift in Sources */,
5B1FD96D1E4E2B6B0055C1AC /* PasswordlessActivity.swift in Sources */,
5B55F3C91E24273D00B75CF5 /* UnrecoverableErrorView.swift in Sources */,
5B9A54441E4B275E004B5454 /* PasswordlessInteractor.swift in Sources */,
Expand All @@ -1079,7 +1090,7 @@
5B3440C51E7C09A1009F8BF7 /* PasswordlessRouter.swift in Sources */,
5F92C68F1D50EAC200CCE6C0 /* LazyImage.swift in Sources */,
5F2496BA1D665AE900A1C6E2 /* CredentialAuthError.swift in Sources */,
5B3DA2531E6DE88900370C17 /* CountrySelectorView.swift in Sources */,
5B3DA2531E6DE88900370C17 /* InternationalPhoneInputView.swift in Sources */,
5B9A54461E4B2CB4004B5454 /* PasswordlessAuthenticatable.swift in Sources */,
5B55F3CB1E242A2E00B75CF5 /* UnrecoverableErrorPresenter.swift in Sources */,
5F57DFC61D4F79DD00C54DA8 /* AuthStyle.swift in Sources */,
Expand Down Expand Up @@ -1107,6 +1118,7 @@
5F50900E1D1DF40400EAA650 /* DatabaseOnlyView.swift in Sources */,
5F70F1E91D7907D5004698DA /* LockOptions.swift in Sources */,
5FC4348A1D1DF82A005188BC /* DatabasePresenter.swift in Sources */,
5B889AF01E7022B900C9FBAF /* ControllerModalPresenter.swift in Sources */,
5F70F1EE1D790BBE004698DA /* LockViewController.swift in Sources */,
5F5D4A261DC3FB34002A38EB /* PasswordPolicyView.swift in Sources */,
5F99AA821D1B0A3900D27842 /* i18n.swift in Sources */,
Expand Down
56 changes: 56 additions & 0 deletions Lock/ControllerModalPresenter.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// ControllerModalPresenter.swift
//
// Copyright (c) 2017 Auth0 (http:https://auth0.com)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

import UIKit

struct ControllerModalPresenter {

var rootViewController: UIViewController? {
return UIApplication.shared.keyWindow?.rootViewController
}

func present(controller: UIViewController) {
topViewController?.present(controller, animated: true, completion: nil)
}

var topViewController: UIViewController? {
guard let root = self.rootViewController else { return nil }
return findTopViewController(from: root)
}

private func findTopViewController(from root: UIViewController) -> UIViewController? {
if let presented = root.presentedViewController { return findTopViewController(from: presented) }
switch root {
case let split as UISplitViewController:
guard let last = split.viewControllers.last else { return split }
return findTopViewController(from: last)
case let navigation as UINavigationController:
guard let top = navigation.topViewController else { return navigation }
return findTopViewController(from: top)
case let tab as UITabBarController:
guard let selected = tab.selectedViewController else { return tab }
return findTopViewController(from: selected)
default:
return root
}
}
}
30 changes: 25 additions & 5 deletions Lock/TableViewController.swift → Lock/CountryCodeStore.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// TableViewController.swift
// CountryCodeStore.swift
//
// Copyright (c) 2017 Auth0 (http:https://auth0.com)
//
Expand All @@ -20,12 +20,32 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

import UIKit
import Foundation

class TableViewController: UITableViewController {
struct CountryCodeStore {

override func viewDidLoad() {
super.viewDidLoad()
var countryCodes: [CountryCode] = []

init() {
guard
let url = bundleForLock().url(forResource: "passwordless_sms_countries", withExtension: "json"),
let jsonData = try? Data(contentsOf: url),
let jsonResult = try? JSONSerialization.jsonObject(with: jsonData) as! [String: String]
else { return }

countryCodes = jsonResult.flatMap { key, value in
let name = (Locale.current as NSLocale).displayName(forKey: .countryCode, value: key)
return CountryCode(id: key, prefix: value, name: name!)
}.sorted { $0.name.localizedCaseInsensitiveCompare($1.name) == ComparisonResult.orderedAscending }
}

func countryCode(forId id: String) -> CountryCode {
return self.countryCodes.filter { $0.id == id }.first!
}
}

struct CountryCode {
let id: String
let prefix: String
let name: String
}
64 changes: 64 additions & 0 deletions Lock/CountryTableViewController.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// CountryTableViewController.swift
//
// Copyright (c) 2017 Auth0 (http:https://auth0.com)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

import UIKit

class CountryTableViewController: UITableViewController {

let dataStore: CountryCodeStore
let cellReuseIdentifier = "CountryCodeCell"

var onDidSelect: (CountryCode) -> Void = { _ in }

init(withData dataStore: CountryCodeStore) {
self.dataStore = dataStore
super.init(style: .grouped)
}

required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

override func viewDidLoad() {
super.viewDidLoad()
tableView.contentInset = UIEdgeInsets(top: 25, left: 0, bottom: 0, right: 0)
tableView.register(UITableViewCell.self, forCellReuseIdentifier: cellReuseIdentifier)
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return dataStore.countryCodes.count
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cellData = dataStore.countryCodes[indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier, for: indexPath)
cell.textLabel?.text = cellData.name + " " + cellData.prefix
return cell
}

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cellData = dataStore.countryCodes[indexPath.row]
self.onDidSelect(cellData)
self.dismiss(animated: true, completion: nil)
}

}
4 changes: 4 additions & 0 deletions Lock/Form.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,7 @@ import Foundation
var onReturn: (InputField) -> Void { get set }
func needsToUpdateState()
}

protocol PasswordlessSMSForm: Form {
var onCountryChange: (CountryCode) -> Void { get set }
}
4 changes: 1 addition & 3 deletions Lock/InputField.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

import UIKit

class InputField: UIView, UITextFieldDelegate, Form {
class InputField: UIView, UITextFieldDelegate {

weak var containerView: UIView?
weak var textField: UITextField?
Expand Down Expand Up @@ -75,8 +75,6 @@ class InputField: UIView, UITextFieldDelegate, Form {

var onEndEditing: (InputField) -> Void = {_ in}

var onValueChange: (InputField) -> Void = {_ in}

// MARK: - Initialisers

convenience init() {
Expand Down
Loading

0 comments on commit ac3a21f

Please sign in to comment.