Skip to content
Open
Show file tree
Hide file tree
Changes from 6 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.3"
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)
}

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

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: StringHandler?
weak var delegate: DialogManagerDelegate?

enum DialogType {
case alert(blocking: Bool)
case optionalUpdate(updateURL: URL)
case requiredUpdate(updateURL: URL)
}
init(withStringHandler stringHandler: StringHandler? = nil, andDelegate delegate: DialogManagerDelegate? = nil) {
self.stringHandler = stringHandler
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"),
Comment thread
charvoa marked this conversation as resolved.
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"),
Comment thread
charvoa marked this conversation as resolved.
style: .default) { (_) -> Void in
if UIApplication.shared.canOpenURL(updateURL) {
DispatchQueue.main.async { [] in
UIApplication.shared.openURL(updateURL)
}
}
}
}
}
}

}
Loading