From 5525c371ade451afe700e72acc3a723de9bf6e7e Mon Sep 17 00:00:00 2001 From: Milen Halachev Date: Wed, 18 Sep 2019 11:42:17 +0300 Subject: [PATCH] - set version to 1.8.0 - deprecated NSError+Presentation and title is no longer localized, due to genstrings errors - UIViewController+ErrorAlert - as a replacement of NSError+Presentation - updated using Xcode 11 GM seed 2 --- MHAppKit.podspec | 4 +- MHAppKit.xcodeproj/project.pbxproj | 6 ++ .../Foundation/NSError+Presentation.swift | 6 +- .../UIViewController+ErrorAlert.swift | 84 +++++++++++++++++++ 4 files changed, 96 insertions(+), 4 deletions(-) create mode 100644 MHAppKit/Extensions/UIKit/UIViewController/UIViewController+ErrorAlert.swift diff --git a/MHAppKit.podspec b/MHAppKit.podspec index 4ca8e12..40f4f69 100644 --- a/MHAppKit.podspec +++ b/MHAppKit.podspec @@ -1,14 +1,14 @@ Pod::Spec.new do |s| s.name = "MHAppKit" - s.version = "1.7.1" + s.version = "1.8.0" s.source = { :git => "https://github.com/KoCMoHaBTa/#{s.name}.git", :tag => "#{s.version}" } s.license = { :type => "MIT", :file => "LICENSE" } s.author = "Milen Halachev" s.summary = "A collection of useful tools that makes developer's life easier." s.homepage = "https://github.com/KoCMoHaBTa/#{s.name}" - s.swift_version = "5.0" + s.swift_version = "5.1" s.ios.deployment_target = "8.1" s.source_files = "#{s.name}/**/*.swift", "#{s.name}/**/*.{h,m}" diff --git a/MHAppKit.xcodeproj/project.pbxproj b/MHAppKit.xcodeproj/project.pbxproj index 9c8b3d0..c913d72 100644 --- a/MHAppKit.xcodeproj/project.pbxproj +++ b/MHAppKit.xcodeproj/project.pbxproj @@ -80,6 +80,7 @@ E65AA39B21CBA72900E58856 /* OperationQueue+Completion.swift in Sources */ = {isa = PBXBuildFile; fileRef = E65AA39A21CBA72900E58856 /* OperationQueue+Completion.swift */; }; E65AA39D21CBA8B500E58856 /* OperationQueueTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E65AA39C21CBA8B500E58856 /* OperationQueueTests.swift */; }; E66FEC7F20595957003C8761 /* UISegmentedControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = E66FEC7E20595957003C8761 /* UISegmentedControl.swift */; }; + E677AA2D23312D47004B2CFA /* UIViewController+ErrorAlert.swift in Sources */ = {isa = PBXBuildFile; fileRef = E677AA2C23312D47004B2CFA /* UIViewController+ErrorAlert.swift */; }; E680314221A20A7F003D0159 /* String+NilEmpty.swift in Sources */ = {isa = PBXBuildFile; fileRef = E680314121A20A7F003D0159 /* String+NilEmpty.swift */; }; E69113B620E4FCC600749F6B /* UIApplication+BackgroundTask.swift in Sources */ = {isa = PBXBuildFile; fileRef = E69113B520E4FCC600749F6B /* UIApplication+BackgroundTask.swift */; }; E69113B820E4FD1200749F6B /* String+UUID.swift in Sources */ = {isa = PBXBuildFile; fileRef = E69113B720E4FD1200749F6B /* String+UUID.swift */; }; @@ -244,6 +245,7 @@ E65AA39A21CBA72900E58856 /* OperationQueue+Completion.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OperationQueue+Completion.swift"; sourceTree = ""; }; E65AA39C21CBA8B500E58856 /* OperationQueueTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OperationQueueTests.swift; sourceTree = ""; }; E66FEC7E20595957003C8761 /* UISegmentedControl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UISegmentedControl.swift; sourceTree = ""; }; + E677AA2C23312D47004B2CFA /* UIViewController+ErrorAlert.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIViewController+ErrorAlert.swift"; sourceTree = ""; }; E680314121A20A7F003D0159 /* String+NilEmpty.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+NilEmpty.swift"; sourceTree = ""; }; E69113B520E4FCC600749F6B /* UIApplication+BackgroundTask.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIApplication+BackgroundTask.swift"; sourceTree = ""; }; E69113B720E4FD1200749F6B /* String+UUID.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+UUID.swift"; sourceTree = ""; }; @@ -457,6 +459,7 @@ 3035211B1C88F00D00436351 /* UIViewController+Lookup.swift */, 3035211C1C88F00D00436351 /* UIViewController+UIAlertController.swift */, 3035211A1C88F00D00436351 /* UIViewController+Container.swift */, + E677AA2C23312D47004B2CFA /* UIViewController+ErrorAlert.swift */, ); path = UIViewController; sourceTree = ""; @@ -914,6 +917,7 @@ 303521151C88EF6A00436351 /* UIViewTransitionAnimator.swift in Sources */, E6FE9F3D1F2622500094CC5B /* Date+Formatting.swift in Sources */, 303521121C88EF6A00436351 /* ViewController.swift in Sources */, + E677AA2D23312D47004B2CFA /* UIViewController+ErrorAlert.swift in Sources */, E65AA39B21CBA72900E58856 /* OperationQueue+Completion.swift in Sources */, 3035210C1C88EF6A00436351 /* DynamicTableViewController.swift in Sources */, E630CB802145C1B200386CBF /* StringProtocol+OptionalConcat.swift in Sources */, @@ -1090,6 +1094,7 @@ MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; + SUPPORTS_MACCATALYST = NO; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; @@ -1140,6 +1145,7 @@ IPHONEOS_DEPLOYMENT_TARGET = 8.1; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; + SUPPORTS_MACCATALYST = NO; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; diff --git a/MHAppKit/Extensions/Foundation/NSError+Presentation.swift b/MHAppKit/Extensions/Foundation/NSError+Presentation.swift index 01aca13..0db8ead 100644 --- a/MHAppKit/Extensions/Foundation/NSError+Presentation.swift +++ b/MHAppKit/Extensions/Foundation/NSError+Presentation.swift @@ -12,6 +12,7 @@ import UIKit extension NSError { ///Shows an alert, representing the receiver, from a given view controller + @available(*, deprecated, message: "Use UIViewController.showError(_:title:closeTitle:retryTitle:closeHandler:backgroundHandler:retryHandler:) instead.") open func showAlert(from controller: UIViewController?) { self.showAlert(from: controller, retry: nil) @@ -21,15 +22,16 @@ extension NSError { Shows an alert, representing the receiver, from a given view controller with retry handler. The alert shown has the following characteristics: - - title: `NSLocalizedString(self.domain, comment: "")` + - title: `self.domain` - message: `self.localizedDescription` - cancel action: NSLocalizedString("Close", comment: "") - retry action: NSLocalizedString("Retry", comment: "") */ + @available(*, deprecated, message: "Use UIViewController.showError(_:title:closeTitle:retryTitle:closeHandler:backgroundHandler:retryHandler:) instead.") open func showAlert(from controller: UIViewController?, retry: (() -> Void)?) { - let title = NSLocalizedString(self.domain, comment: "") + let title = self.domain let message = self.localizedDescription let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert) diff --git a/MHAppKit/Extensions/UIKit/UIViewController/UIViewController+ErrorAlert.swift b/MHAppKit/Extensions/UIKit/UIViewController/UIViewController+ErrorAlert.swift new file mode 100644 index 0000000..b8a8f1d --- /dev/null +++ b/MHAppKit/Extensions/UIKit/UIViewController/UIViewController+ErrorAlert.swift @@ -0,0 +1,84 @@ +// +// UIViewController+ErrorAlert.swift +// MHAppKit +// +// Created by Milen Halachev on 17.09.19. +// Copyright © 2019 Milen Halachev. All rights reserved. +// + +import Foundation +import UIKit +import UserNotifications + +extension UIViewController { + + ///A default handler, which is executed in case the app is in backgroud when `UIViewController.showError(_:title:closeTitle:retryTitle:closeHandler:backgroundHandler:retryHandler:)` is called. Default to showing a local notification with the provided title and message. In case you'd like to customize this behaviour, eg. adding actions - you can provude your own custom default handler. + public static var showErrorDefaultBackgroundHandler: (String, String?) -> Void = { (title, message) in + + //show local notification + if #available(iOS 10.0, *) { + + let content = UNMutableNotificationContent(title: title, body: message) + let request = UNNotificationRequest(content: content) + UNUserNotificationCenter.current().add(request, withCompletionHandler: nil) + } + else { + + let notification = UILocalNotification() + notification.fireDate = nil + notification.alertBody = message + + if #available(iOS 8.2, *) { + + notification.alertTitle = title + } + + UIApplication.shared.scheduleLocalNotification(notification) + } + } + + /** + Shows an alert representation of a given error within the receiver's context. If the alert is presented withing a background state - a local notification is also shown. + + - parameter error: The error to show. If nil, no error will be shown. This parameter is optional for convenience. + - parameter title: The alert title. + - parameter closeTitle: The title of the close button of the alert. Default to `NSLocalizedString("Close", comment: "")`. + - parameter retryTitle: The title of the retry button of the alert. Default to `NSLocalizedString("Retry", comment: "")`. + - parameter backgroundHandler: An optional handler, executed if the alert is gong to be shown, when the app is in the background. Default to `UIViewController.showErrorDefaultBackgroundHandler`, which shows a local notification. + - parameter closeHandler: An optional close handler. Default to `nil`. + - parameter retryHandler: An optional retry handler. If `nil`, no retry option is presented. + */ + + func showError(_ error: Error?, title: String, closeTitle: String = NSLocalizedString("Close", comment: ""), retryTitle: String = NSLocalizedString("Retry", comment: ""), closeHandler: (() -> Void)? = nil, backgroundHandler: ((String, String?) -> Void)? = UIViewController.showErrorDefaultBackgroundHandler, retryHandler: (() -> Void)?) { + + guard let error = error else { + + return + } + + let message = error.localizedDescription + + if UIApplication.shared.applicationState != .active { + + backgroundHandler?(title, message) + } + + var actions: [UIAlertAction] = [ + + UIAlertAction(title: closeTitle, style: .cancel, handler: { (_) in + + closeHandler?() + }) + ] + + if let retryHandler = retryHandler { + + actions.append(UIAlertAction(title: retryTitle, style: .default, handler: { (_) in + + retryHandler() + })) + } + + self.showAlertView(title: title, message: message, actions: actions) + } +}