Initial project setup.
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
//
|
||||
// AppDelegate.swift
|
||||
// Wireguard
|
||||
//
|
||||
// Created by Jeroen Leenarts on 23-05-18.
|
||||
// Copyright © 2018 Wireguard. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
@UIApplicationMain
|
||||
class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
|
||||
var window: UIWindow?
|
||||
var appCoordinator: AppCoordinator!
|
||||
|
||||
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
|
||||
|
||||
self.window = UIWindow(frame: UIScreen.main.bounds)
|
||||
self.appCoordinator = AppCoordinator(window: self.window!)
|
||||
self.appCoordinator.start()
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "20x20",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "20x20",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "29x29",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "29x29",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "40x40",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "40x40",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "60x60",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "60x60",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "20x20",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "20x20",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "29x29",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "29x29",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "40x40",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "40x40",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "76x76",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "76x76",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "83.5x83.5",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ios-marketing",
|
||||
"size" : "1024x1024",
|
||||
"scale" : "1x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13122.16" systemVersion="17A277" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--View Controller-->
|
||||
<scene sceneID="EHf-IW-A2E">
|
||||
<objects>
|
||||
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
|
||||
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
|
||||
</view>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="53" y="375"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
</document>
|
||||
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14109" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
|
||||
<device id="retina4_7" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14088"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--Connections Table View Controller-->
|
||||
<scene sceneID="Tud-vM-cYZ">
|
||||
<objects>
|
||||
<tableViewController storyboardIdentifier="ConnectionsTableViewController" id="kTU-BV-32R" customClass="ConnectionsTableViewController" customModule="Wireguard" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" id="AJg-r0-KJH">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<prototypes>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" id="fM3-cC-KPN">
|
||||
<rect key="frame" x="0.0" y="28" width="375" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="fM3-cC-KPN" id="Rv6-XK-aK2">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</tableViewCellContentView>
|
||||
</tableViewCell>
|
||||
</prototypes>
|
||||
<connections>
|
||||
<outlet property="dataSource" destination="kTU-BV-32R" id="E0F-RC-fZE"/>
|
||||
<outlet property="delegate" destination="kTU-BV-32R" id="b6T-ZR-cmO"/>
|
||||
</connections>
|
||||
</tableView>
|
||||
</tableViewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="4uZ-Vv-Fry" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="34" y="154"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
</document>
|
||||
@@ -0,0 +1,102 @@
|
||||
//
|
||||
// AppCoordinator.swift
|
||||
// Wireguard
|
||||
//
|
||||
// Created by Jeroen Leenarts on 23-05-18.
|
||||
// Copyright © 2018 Wireguard. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
import CoreData
|
||||
import BNRCoreDataStack
|
||||
|
||||
class AppCoordinator: RootViewCoordinator {
|
||||
|
||||
let persistentContainer = NSPersistentContainer(name: "Wireguard")
|
||||
let storyboard = UIStoryboard(name: "Main", bundle: nil)
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
var childCoordinators: [Coordinator] = []
|
||||
|
||||
var rootViewController: UIViewController {
|
||||
return self.connectionsTableViewController
|
||||
}
|
||||
|
||||
var connectionsTableViewController: ConnectionsTableViewController!
|
||||
|
||||
/// Window to manage
|
||||
let window: UIWindow
|
||||
|
||||
let navigationController: UINavigationController = {
|
||||
let navController = UINavigationController()
|
||||
return navController
|
||||
}()
|
||||
|
||||
// MARK: - Init
|
||||
public init(window: UIWindow) {
|
||||
self.window = window
|
||||
|
||||
self.window.rootViewController = self.navigationController
|
||||
self.window.makeKeyAndVisible()
|
||||
}
|
||||
|
||||
// MARK: - Functions
|
||||
|
||||
/// Starts the coordinator
|
||||
public func start() {
|
||||
persistentContainer.viewContext.automaticallyMergesChangesFromParent = true
|
||||
persistentContainer.loadPersistentStores { [weak self] (_, error) in
|
||||
if let error = error {
|
||||
print("Unable to Load Persistent Store. \(error), \(error.localizedDescription)")
|
||||
|
||||
} else {
|
||||
DispatchQueue.main.async {
|
||||
//start
|
||||
if let connectionsTableViewController = self?.storyboard.instantiateViewController(type: ConnectionsTableViewController.self) {
|
||||
self?.connectionsTableViewController = connectionsTableViewController
|
||||
self?.connectionsTableViewController.viewContext = self?.persistentContainer.viewContext
|
||||
self?.connectionsTableViewController.delegate = self
|
||||
self?.navigationController.viewControllers = [connectionsTableViewController]
|
||||
do {
|
||||
if let context = self?.persistentContainer.viewContext, try Profile.countInContext(context) == 0 {
|
||||
print("No profiles ... yet")
|
||||
}
|
||||
} catch {
|
||||
self?.showError(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func showError(_ error: Error) {
|
||||
showAlert(title: NSLocalizedString("Error", comment: "Error alert title"), message: error.localizedDescription)
|
||||
}
|
||||
|
||||
private func showAlert(title: String, message: String) {
|
||||
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
|
||||
alert.addAction(UIAlertAction(title: NSLocalizedString("OK", comment: "OK button"), style: .default))
|
||||
self.navigationController.present(alert, animated: true)
|
||||
}
|
||||
}
|
||||
|
||||
extension AppCoordinator: ConnectionsTableViewControllerDelegate {
|
||||
func addProvider(connectionsTableViewController: ConnectionsTableViewController) {
|
||||
// TODO implement
|
||||
}
|
||||
|
||||
func settings(connectionsTableViewController: ConnectionsTableViewController) {
|
||||
// TODO implement
|
||||
}
|
||||
|
||||
func connect(profile: Profile) {
|
||||
// TODO implement
|
||||
}
|
||||
|
||||
func delete(profile: Profile) {
|
||||
// TODO implement
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
//
|
||||
// Coordinator.swift
|
||||
// Wireguard
|
||||
//
|
||||
// Created by Jeroen Leenarts on 23-05-18.
|
||||
// Copyright © 2018 Wireguard. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
/// The Coordinator protocol
|
||||
public protocol Coordinator: class {
|
||||
|
||||
/// Starts the coordinator
|
||||
func start()
|
||||
|
||||
/// The array containing any child Coordinators
|
||||
var childCoordinators: [Coordinator] { get set }
|
||||
|
||||
}
|
||||
|
||||
public extension Coordinator {
|
||||
|
||||
/// Add a child coordinator to the parent
|
||||
public func addChildCoordinator(_ childCoordinator: Coordinator) {
|
||||
self.childCoordinators.append(childCoordinator)
|
||||
}
|
||||
|
||||
/// Remove a child coordinator from the parent
|
||||
public func removeChildCoordinator(_ childCoordinator: Coordinator) {
|
||||
self.childCoordinators = self.childCoordinators.filter { $0 !== childCoordinator }
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
//
|
||||
// RootCoordinator.swift
|
||||
// Wireguard
|
||||
//
|
||||
// Created by Jeroen Leenarts on 23-05-18.
|
||||
// Copyright © 2018 Wireguard. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
|
||||
public protocol RootViewControllerProvider: class {
|
||||
// The coordinators 'rootViewController'. It helps to think of this as the view
|
||||
// controller that can be used to dismiss the coordinator from the view hierarchy.
|
||||
var rootViewController: UIViewController { get }
|
||||
}
|
||||
|
||||
/// A Coordinator type that provides a root UIViewController
|
||||
public typealias RootViewCoordinator = Coordinator & RootViewControllerProvider
|
||||
@@ -0,0 +1,43 @@
|
||||
<?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>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>auto-generated</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
<array>
|
||||
<string>armv7</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,16 @@
|
||||
//
|
||||
// Profile+CoreDataClass.swift
|
||||
// Wireguard
|
||||
//
|
||||
// Created by Jeroen Leenarts on 23-05-18.
|
||||
// Copyright © 2018 Wireguard. All rights reserved.
|
||||
//
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import CoreData
|
||||
|
||||
@objc(Profile)
|
||||
public class Profile: NSManagedObject {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
//
|
||||
// Profile+CoreDataProperties.swift
|
||||
// Wireguard
|
||||
//
|
||||
// Created by Jeroen Leenarts on 23-05-18.
|
||||
// Copyright © 2018 Wireguard. All rights reserved.
|
||||
//
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import CoreData
|
||||
|
||||
extension Profile {
|
||||
|
||||
@nonobjc public class func fetchRequest() -> NSFetchRequest<Profile> {
|
||||
return NSFetchRequest<Profile>(entityName: "Profile")
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="14133" systemVersion="17E202" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
|
||||
<entity name="Profile" representedClassName="Profile" syncable="YES"/>
|
||||
<elements>
|
||||
<element name="Profile" positionX="-63" positionY="-18" width="128" height="45"/>
|
||||
</elements>
|
||||
</model>
|
||||
@@ -0,0 +1,38 @@
|
||||
//
|
||||
// ConnectionsTableViewController.swift
|
||||
// Wireguard
|
||||
//
|
||||
// Created by Jeroen Leenarts on 23-05-18.
|
||||
// Copyright © 2018 Wireguard. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
import CoreData
|
||||
import BNRCoreDataStack
|
||||
|
||||
protocol ConnectionsTableViewControllerDelegate: class {
|
||||
func addProvider(connectionsTableViewController: ConnectionsTableViewController)
|
||||
func settings(connectionsTableViewController: ConnectionsTableViewController)
|
||||
func connect(profile: Profile)
|
||||
func delete(profile: Profile)
|
||||
}
|
||||
|
||||
class ConnectionsTableViewController: UITableViewController {
|
||||
weak var delegate: ConnectionsTableViewControllerDelegate?
|
||||
|
||||
var viewContext: NSManagedObjectContext!
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
// Do any additional setup after loading the view, typically from a nib.
|
||||
}
|
||||
|
||||
override func didReceiveMemoryWarning() {
|
||||
super.didReceiveMemoryWarning()
|
||||
// Dispose of any resources that can be recreated.
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension ConnectionsTableViewController: Identifyable {}
|
||||
@@ -0,0 +1,27 @@
|
||||
//
|
||||
// Identifyable.swift
|
||||
// Wireguard
|
||||
//
|
||||
// Created by Jeroen Leenarts on 23-05-18.
|
||||
// Copyright © 2018 Wireguard. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
|
||||
public protocol Identifyable: class {
|
||||
static var identifier: String { get }
|
||||
}
|
||||
|
||||
public extension Identifyable {
|
||||
static var identifier: String {
|
||||
return String(describing: Self.self)
|
||||
}
|
||||
}
|
||||
|
||||
extension UIStoryboard {
|
||||
|
||||
public func instantiateViewController<T: Identifyable>(type: T.Type) -> T where T: UIViewController {
|
||||
return self.instantiateViewController(withIdentifier: type.identifier) as! T // swiftlint:disable:this force_cast
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user