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
2 changes: 1 addition & 1 deletion LaunchGate.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "LaunchGate"
s.version = "1.1.1"
s.version = "1.1.4"
s.summary = <<-SUMMARY
LaunchGate makes it easy to let users know when an update to your app is available.
SUMMARY
Expand Down
138 changes: 70 additions & 68 deletions Source/DefaultParser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,83 +10,85 @@ 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."
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 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)
}
}
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)")
return nil
} catch let error as NSError {
print("LaunchGate — Error: \(error.localizedDescription)")

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

return nil
}
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 }
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)
}
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 }
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)
}
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 }
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)
}
return UpdateConfiguration(version: version, message: message)
}

}
154 changes: 87 additions & 67 deletions Source/DialogManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,100 +8,120 @@

import Foundation

public protocol DialogManagerDelegate: class {
func didDismissAlertView()
}

// Localization of strings

protocol Dialogable {
var message: String { get }
var message: String { get }
}

class DialogManager {

typealias RememberableDialogSubject = Dialogable & Rememberable
typealias RememberableDialogSubject = Dialogable & Rememberable

enum DialogType {
case alert(blocking: Bool)
case optionalUpdate(updateURL: URL)
case requiredUpdate(updateURL: URL)
}

var stringHandler: WordingHandler?
weak var delegate: DialogManagerDelegate?

enum DialogType {
case alert(blocking: Bool)
case optionalUpdate(updateURL: URL)
case requiredUpdate(updateURL: URL)
}
init(withWordingHandler wordingHandler: WordingHandler? = nil,
andDelegate delegate: DialogManagerDelegate? = nil) {
self.stringHandler = wordingHandler
self.delegate = delegate
}

func displayAlertDialog(_ alertConfig: RememberableDialogSubject, blocking: Bool) {
let dialog = createAlertController(.alert(blocking: blocking), message: alertConfig.message)
func displayAlertDialog(_ alertConfig: RememberableDialogSubject, blocking: Bool) {
let dialog = createAlertController(.alert(blocking: blocking),
message: stringHandler?.alertMessage ?? alertConfig.message)

displayAlertController(dialog) { () -> Void in
if !blocking {
Memory.remember(alertConfig)
}
displayAlertController(dialog) { () -> Void in
if !blocking {
Memory.remember(alertConfig)
}
}
}
}

func displayRequiredUpdateDialog(_ updateConfig: Dialogable, updateURL: URL) {
let dialog = createAlertController(.requiredUpdate(updateURL: updateURL), message: updateConfig.message)
func displayRequiredUpdateDialog(_ updateConfig: Dialogable, updateURL: URL) {
let dialog = createAlertController(.requiredUpdate(updateURL: updateURL),
message: stringHandler?.requiredUpdateMessage ?? updateConfig.message)

displayAlertController(dialog, completion: nil)
}
displayAlertController(dialog, completion: nil)
}

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

displayAlertController(dialog) { () -> Void in
Memory.remember(updateConfig)
displayAlertController(dialog) { () -> Void in
Memory.remember(updateConfig)
}
}
}

// MARK: Custom Alert Controllers
// MARK: Custom Alert Controllers

func createAlertController(_ type: DialogType, message: String) -> UIAlertController {
let alertController = UIAlertController(title: nil, message: message, preferredStyle: .alert)
func createAlertController(_ type: DialogType, message: String) -> UIAlertController {
let alertController = UIAlertController(title: nil, message: message, preferredStyle: .alert)

switch type {
case let .alert(blocking):
if !blocking {
switch type {
case let .alert(blocking):
if !blocking {
alertController.addAction(dismissActon())
}

case let .optionalUpdate(updateURL):
alertController.addAction(dismissActon())
alertController.addAction(updateAction(updateURL))

case let .requiredUpdate(updateURL):
alertController.addAction(updateAction(updateURL))
}

case let .optionalUpdate(updateURL):
alertController.addAction(dismissActon())
alertController.addAction(updateAction(updateURL))
return alertController
}

case let .requiredUpdate(updateURL):
alertController.addAction(updateAction(updateURL))
func displayAlertController(_ alert: UIAlertController, completion: (() -> Void)?) {
DispatchQueue.main.async { [] in
if let topViewController = self.topViewController() {
topViewController.present(alert, animated: true) {
if let completion = completion {
completion()
}
}
}
}
}

return alertController
}
func topViewController() -> UIViewController? {
return UIApplication.shared.keyWindow?.rootViewController
}

// MARK: Custom Alert Actions

func displayAlertController(_ alert: UIAlertController, completion: (() -> Void)?) {
DispatchQueue.main.async { [] in
if let topViewController = self.topViewController() {
topViewController.present(alert, animated: true) {
if let completion = completion {
completion()
}
private func dismissActon() -> UIAlertAction {
return UIAlertAction(
title: NSLocalizedString(stringHandler?.dismissTitle ?? "Dismiss", comment: "Button title for dismissing the update AlertView"),
style: .default) { _ in
self.delegate?.didDismissAlertView()
}
}
}
}

func topViewController() -> UIViewController? {
return UIApplication.shared.keyWindow?.rootViewController
}

// MARK: Custom Alert Actions

private func dismissActon() -> UIAlertAction {
return UIAlertAction(
title: NSLocalizedString("Dismiss", comment: "Button title for dismissing the update AlertView"),
style: .default) { _ in }
}

private func updateAction(_ updateURL: URL) -> UIAlertAction {
return UIAlertAction(
title: NSLocalizedString("Update", comment: "Button title for accepting the update AlertView"),
style: .default) { (_) -> Void in
if UIApplication.shared.canOpenURL(updateURL) {
DispatchQueue.main.async { [] in
UIApplication.shared.openURL(updateURL)

private func updateAction(_ updateURL: URL) -> UIAlertAction {
return UIAlertAction(
title: NSLocalizedString(stringHandler?.downloadTitle ?? "Update", comment: "Button title for accepting the update AlertView"),
style: .default) { (_) -> Void in
if UIApplication.shared.canOpenURL(updateURL) {
DispatchQueue.main.async { [] in
UIApplication.shared.openURL(updateURL)
}
}
}
}
}
}

}
Loading