Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
4255cf4
Added import command for UIKit; resolved 6 build errors
BritneyS Nov 12, 2018
1248e2e
Added line to disable SwiftLint rule that did not allow valid charact…
BritneyS Nov 12, 2018
2b1a386
Updated build settings to use Swift 4.2 in root, removed unnecessary …
BritneyS Nov 12, 2018
b5fc306
Conformed models to Codable, changed vars to lets
BritneyS Nov 12, 2018
53ebcf1
Starting replacing parsing methods using JSOnDecoder
BritneyS Nov 13, 2018
f9d1b73
Rewrote more parsing methods
BritneyS Nov 13, 2018
91697fc
Wrote decoder initializer
BritneyS Nov 13, 2018
828aeb0
WIP: Parser method
BritneyS Nov 13, 2018
46ed62f
WIP - Decoding LaunchGateConfiguration
BritneyS Nov 13, 2018
8859add
WIP - changed container for root JSON object
BritneyS Nov 14, 2018
5c72248
WIP - decoding rook object in nested container
BritneyS Nov 14, 2018
b1a18cd
WIP - changed comment
BritneyS Nov 14, 2018
c0ad046
WIP - Fixed decoder initializer
BritneyS Nov 14, 2018
5065dd0
WIP - trying CodingKey struct
BritneyS Nov 14, 2018
d41da41
WIP - decoding changes
BritneyS Nov 14, 2018
3d8fe1d
Changed decoding in UpdateConfiguration: accounted for possibility fo…
BritneyS Nov 14, 2018
7f0a82e
WIP - possible async issue; properties not available before parse
BritneyS Nov 14, 2018
eeb19bd
Preparing changes for review
BritneyS Nov 15, 2018
0155f52
WIP - decoded root object
BritneyS Nov 15, 2018
ddb66ed
Removed optionals; decoded nested objects 'alert', 'optionalUpdate' a…
BritneyS Nov 15, 2018
358a5fe
WIP - parsing
BritneyS Nov 15, 2018
e751542
WIP - at this point, data is parsed, still with JSONSerialization
BritneyS Nov 15, 2018
3291550
WIP - Changed manual decoding
BritneyS Nov 16, 2018
b01e6e7
Replaced parsing method with one that uses JSONDecoder; parsing works…
BritneyS Nov 16, 2018
3dae3db
Cleanup - Removed unnecessary print statements, commented out code. R…
BritneyS Nov 16, 2018
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
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@
"idiom" : "iphone",
"size" : "60x60",
"scale" : "3x"
},
{
"idiom" : "ios-marketing",
"size" : "1024x1024",
"scale" : "1x"
}
],
"info" : {
Expand Down
6 changes: 2 additions & 4 deletions LaunchGate.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,7 @@
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 4.2;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
Expand Down Expand Up @@ -555,6 +556,7 @@
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_VERSION = 4.2;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
VERSIONING_SYSTEM = "apple-generic";
Expand All @@ -579,7 +581,6 @@
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 4.0;
};
name = Debug;
};
Expand All @@ -599,7 +600,6 @@
PRODUCT_BUNDLE_IDENTIFIER = com.dtrenz.LaunchGate;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_VERSION = 4.0;
};
name = Release;
};
Expand All @@ -611,7 +611,6 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.dtrenz.LaunchGateTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 4.0;
};
name = Debug;
};
Expand All @@ -623,7 +622,6 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.dtrenz.LaunchGateTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 4.0;
};
name = Release;
};
Expand Down
17 changes: 4 additions & 13 deletions LaunchGate.xcodeproj/xcshareddata/xcschemes/LaunchGate.xcscheme
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "C5C04BC51C696767007397D0"
BuildableName = "LaunchGate.framework"
BlueprintName = "LaunchGate"
ReferencedContainer = "container:LaunchGate.xcodeproj">
BlueprintIdentifier = "C5A878881C6A7A95004599C2"
BuildableName = "Example.app"
BlueprintName = "Example"
ReferencedContainer = "container:Example/Example.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
Expand All @@ -62,15 +62,6 @@
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "C5C04BC51C696767007397D0"
BuildableName = "LaunchGate.framework"
BlueprintName = "LaunchGate"
ReferencedContainer = "container:LaunchGate.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
Expand Down
2 changes: 0 additions & 2 deletions Podfile
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
source 'https://github.com/CocoaPods/Specs.git'
use_frameworks!

pod 'SwiftLint'

target 'LaunchGateTests' do
platform :ios, '8.3'
inherit! :search_paths
Expand Down
14 changes: 7 additions & 7 deletions Podfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PODS:
- Nimble (7.1.3)
- Quick (1.3.1)
- SwiftLint (0.26.0)
- Nimble (7.3.1)
- Quick (1.3.2)
- SwiftLint (0.27.0)

DEPENDENCIES:
- Nimble
Expand All @@ -15,10 +15,10 @@ SPEC REPOS:
- SwiftLint

SPEC CHECKSUMS:
Nimble: 2839b01d1b31f6a6a7777a221f0d91cf52e8e27b
Quick: d17304d58d0d169dd0bd1c6e5c28e3318de32a1a
SwiftLint: f6b83e8d95ee1e91e11932d843af4fdcbf3fc764
Nimble: 04f732da099ea4d153122aec8c2a88fd0c7219ae
Quick: 2623cb30d7a7f41ca62f684f679586558f483d46
SwiftLint: 3207c1faa2240bf8973b191820a116113cd11073

PODFILE CHECKSUM: 80b19f99959846e7855de4619381077e49a4e498
PODFILE CHECKSUM: c66a903b4dd3d64e68e8dcb4170d38ac84ba0147

COCOAPODS: 1.5.3
6 changes: 3 additions & 3 deletions Source/AlertConfiguration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@

import Foundation

public struct AlertConfiguration: Dialogable, Rememberable {
public struct AlertConfiguration: Decodable, Dialogable, Rememberable {

var message = ""
var blocking = false
let message: String
let blocking: Bool

init?(message: String, blocking: Bool) {
guard !message.isEmpty else { return nil }
Expand Down
85 changes: 8 additions & 77 deletions Source/DefaultParser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,83 +10,14 @@ import Foundation

class DefaultParser: LaunchGateParser {

typealias JSON = [String: AnyObject]

enum Error: LaunchGateError {
case unableToParseConfigurationObject
case unableToParseAlert
case unableToParseOptionalUpdate
case unableToParseRequiredUpdate

var description: String {
switch self {
case .unableToParseConfigurationObject:
return "Unable to parse the configuration object (\"ios\") from JSON file."
case .unableToParseAlert:
return "Unable to parse the alert configuration from JSON file."
case .unableToParseOptionalUpdate:
return "Unable to parse the optional update configuration from JSON file."
case .unableToParseRequiredUpdate:
return "Unable to parse the required update configuration from JSON file."
func parse(_ jsonData: Data) -> LaunchGateConfiguration? {
do {
let decoder = JSONDecoder()
let result = try decoder.decode(LaunchGateConfiguration.self, from: jsonData)
return result
} catch let error {
print("LaunchGate — Error: \(error)")
}
return nil
}
}

func parse(_ jsonData: Data) -> LaunchGateConfiguration? {
do {
let jsonData = try JSONSerialization.jsonObject(with: jsonData, options: [])
guard let json = jsonData as? JSON else { throw Error.unableToParseConfigurationObject }
guard let config = json["ios"] else { throw Error.unableToParseConfigurationObject }

var alert: AlertConfiguration?
var optionalUpdate: UpdateConfiguration?
var requiredUpdate: UpdateConfiguration?

if let alertJSON = config["alert"] as? JSON {
alert = try DefaultParser.parseAlert(alertJSON)
}

if let optionalUpdateJSON = config["optionalUpdate"] as? JSON {
optionalUpdate = try DefaultParser.parseOptionalUpdate(optionalUpdateJSON)
}

if let requiredUpdateJSON = config["requiredUpdate"] as? JSON {
requiredUpdate = try DefaultParser.parseRequiredUpdate(requiredUpdateJSON)
}

return LaunchGateConfiguration(alert: alert, optionalUpdate: optionalUpdate, requiredUpdate: requiredUpdate)
} catch let error as DefaultParser.Error {
print("LaunchGate — Error: \(error)")
} catch let error as NSError {
print("LaunchGate — Error: \(error.localizedDescription)")

if let recoverySuggestion = error.localizedRecoverySuggestion {
print(recoverySuggestion)
}
}

return nil
}

private static func parseAlert(_ json: JSON) throws -> AlertConfiguration? {
guard let message = json["message"] as? String else { throw Error.unableToParseAlert }
guard let blocking = json["blocking"] as? Bool else { throw Error.unableToParseAlert }

return AlertConfiguration(message: message, blocking: blocking)
}

private static func parseOptionalUpdate(_ json: JSON) throws -> UpdateConfiguration? {
guard let version = json["optionalVersion"] as? String else { throw Error.unableToParseOptionalUpdate }
guard let message = json["message"] as? String else { throw Error.unableToParseOptionalUpdate }

return UpdateConfiguration(version: version, message: message)
}

private static func parseRequiredUpdate(_ json: JSON) throws -> UpdateConfiguration? {
guard let version = json["minimumVersion"] as? String else { throw Error.unableToParseRequiredUpdate }
guard let message = json["message"] as? String else { throw Error.unableToParseRequiredUpdate }

return UpdateConfiguration(version: version, message: message)
}

}
2 changes: 1 addition & 1 deletion Source/DialogManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//

import Foundation
import UIKit

protocol Dialogable {
var message: String { get }
Expand Down Expand Up @@ -40,7 +41,6 @@ class DialogManager {

func displayOptionalUpdateDialog(_ updateConfig: RememberableDialogSubject, updateURL: URL) {
let dialog = createAlertController(.optionalUpdate(updateURL: updateURL), message: updateConfig.message)

displayAlertController(dialog) { () -> Void in
Memory.remember(updateConfig)
}
Expand Down
5 changes: 3 additions & 2 deletions Source/LaunchGate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public class LaunchGate {
/// Manager object for the various alert dialogs
var dialogManager: DialogManager!

//var config: LaunchGateConfiguration!
// MARK: - Public API

/**
Expand All @@ -50,7 +51,7 @@ public class LaunchGate {

/// Check the configuration file and perform any appropriate action.
public func check() {
performCheck(RemoteFileManager(remoteFileURL: (configurationFileURL as URL)))
performCheck(RemoteFileManager(remoteFileURL: (configurationFileURL)))
}

// MARK: - Internal API
Expand All @@ -63,7 +64,7 @@ public class LaunchGate {
*/
func performCheck(_ remoteFileManager: RemoteFileManager) {
remoteFileManager.fetchRemoteFile { (jsonData) -> Void in
if let config = self.parser.parse(jsonData) {
if let config: LaunchGateConfiguration = self.parser.parse(jsonData) {
self.displayDialogIfNecessary(config, dialogManager: self.dialogManager)
}
}
Expand Down
15 changes: 14 additions & 1 deletion Source/LaunchGateConfiguration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import Foundation

/// The configuration object that should be created as the result of parsing the remote configuration file.
public struct LaunchGateConfiguration {
public struct LaunchGateConfiguration: Decodable {

/// An `AlertConfiguration`, parsed from the configuration file.
var alert: AlertConfiguration?
Expand All @@ -20,4 +20,17 @@ public struct LaunchGateConfiguration {
/// A required `UpdateConfiguration`, parsed from the configuration file.
var requiredUpdate: UpdateConfiguration?

public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: IOSCodingKeys.self)
let iosContainer = try container.nestedContainer(keyedBy: IOSCodingKeys.self, forKey: .ios)
alert = try iosContainer.decodeIfPresent(AlertConfiguration.self, forKey: .alert)
optionalUpdate = try iosContainer.decodeIfPresent(UpdateConfiguration.self, forKey: .optionalUpdate)
requiredUpdate = try iosContainer.decodeIfPresent(UpdateConfiguration.self, forKey: .requiredUpdate)
}
enum IOSCodingKeys: String, CodingKey {
case ios
case alert
case optionalUpdate
case requiredUpdate
}
}
2 changes: 1 addition & 1 deletion Source/RemoteFileManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class RemoteFileManager {
func performRemoteFileRequest(_ session: URLSession, url: URL, responseHandler: @escaping (_ data: Data) -> Void) {
let task = session.dataTask(with: url) { data, response, error in
if let error = error {
print("LaunchGate — Error: \(error.localizedDescription)")
print("LaunchGate — Error2: \(error.localizedDescription)")
}
guard response != nil else {
print("LaunchGate - Error because there is no response")
Expand Down
30 changes: 26 additions & 4 deletions Source/UpdateConfiguration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,9 @@

import Foundation

public struct UpdateConfiguration: Dialogable, Rememberable {

var version = ""
var message = ""
public struct UpdateConfiguration: Decodable, Dialogable, Rememberable {
var version: String
var message: String

init?(version: String, message: String) {
guard !version.isEmpty else { return nil }
Expand All @@ -20,6 +19,29 @@ public struct UpdateConfiguration: Dialogable, Rememberable {
self.version = version
self.message = message
}
public init(from decoder: Decoder) throws {
let optionalKeyedContainer = try decoder.container(keyedBy: OptionalCodingKeys.self)
let requiredKeyedContainer = try decoder.container(keyedBy: RequiredCodingKeys.self)
do {
version = try optionalKeyedContainer.decode(String.self, forKey: .version)
message = try optionalKeyedContainer.decode(String.self, forKey: .message)
} catch {
do {
version = try requiredKeyedContainer.decode(String.self, forKey: .version)
message = try requiredKeyedContainer.decode(String.self, forKey: .message)
} catch {
throw error
}
}
}
enum OptionalCodingKeys: String, CodingKey {
case version = "optionalVersion"
case message
}
enum RequiredCodingKeys: String, CodingKey {
case version = "minimumVersion"
case message
}

// MARK: Rememberable Protocol Methods

Expand Down