#535 Remove needless async code

This commit is contained in:
Timothy Moose
2023-12-03 11:54:25 -06:00
parent 95f65d57f0
commit 633b6e593b
9 changed files with 105 additions and 118 deletions
+1 -1
View File
@@ -4,7 +4,7 @@ import PackageDescription
let package = Package(
name: "SwiftMessages",
platforms: [
.iOS("9.0")
.iOS("13.0")
],
products: [
.library(name: "SwiftMessages", targets: ["SwiftMessages"]),
+2 -2
View File
@@ -6,9 +6,9 @@ Pod::Spec.new do |spec|
spec.authors = { 'Timothy Moose' => 'tim@swiftkickmobile.com' }
spec.summary = 'A very flexible message bar for iOS written in Swift.'
spec.source = {:git => 'https://github.com/SwiftKickMobile/SwiftMessages.git', :tag => spec.version}
spec.platform = :ios, '12.0'
spec.platform = :ios, '13.0'
spec.swift_version = '5.0'
spec.ios.deployment_target = '12.0'
spec.ios.deployment_target = '13.0'
spec.framework = 'UIKit'
spec.requires_arc = true
spec.default_subspec = 'App'
+11 -5
View File
@@ -59,6 +59,7 @@
2298C2071EE480D000E2DDC1 /* Animator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2298C2061EE480D000E2DDC1 /* Animator.swift */; };
2298C2091EE486E300E2DDC1 /* TopBottomAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2298C2081EE486E300E2DDC1 /* TopBottomAnimation.swift */; };
229F778125FAB1E9008C2ACB /* UIWindow+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 229F778025FAB1E9008C2ACB /* UIWindow+Extensions.swift */; };
22D3B4562B1CEF76002D8665 /* Task+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22D3B4552B1CEF76002D8665 /* Task+Extensions.swift */; };
22DFC9161EFF30F6001B1CA1 /* CenteredView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 22DFC9151EFF30F6001B1CA1 /* CenteredView.xib */; };
22DFC9181F00674E001B1CA1 /* PhysicsPanHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22DFC9171F00674E001B1CA1 /* PhysicsPanHandler.swift */; };
22E01F641E74EC8B00ACE19A /* MaskingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22E01F631E74EC8B00ACE19A /* MaskingView.swift */; };
@@ -151,6 +152,7 @@
2298C2081EE486E300E2DDC1 /* TopBottomAnimation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TopBottomAnimation.swift; sourceTree = "<group>"; };
229F778025FAB1E9008C2ACB /* UIWindow+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIWindow+Extensions.swift"; sourceTree = "<group>"; };
22A2EA6E24EC6CFA00BB2540 /* Package.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Package.swift; sourceTree = "<group>"; };
22D3B4552B1CEF76002D8665 /* Task+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Task+Extensions.swift"; sourceTree = "<group>"; };
22DFC9151EFF30F6001B1CA1 /* CenteredView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = CenteredView.xib; path = Resources/CenteredView.xib; sourceTree = "<group>"; };
22DFC9171F00674E001B1CA1 /* PhysicsPanHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PhysicsPanHandler.swift; sourceTree = "<group>"; };
22E01F631E74EC8B00ACE19A /* MaskingView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MaskingView.swift; sourceTree = "<group>"; };
@@ -220,6 +222,7 @@
220655111FAF82B600F4E00F /* MarginAdjustable+Extensions.swift */,
22774B9F20B5EF2A00813732 /* UIEdgeInsets+Extensions.swift */,
229F778025FAB1E9008C2ACB /* UIWindow+Extensions.swift */,
22D3B4552B1CEF76002D8665 /* Task+Extensions.swift */,
);
name = Extensions;
sourceTree = "<group>";
@@ -453,7 +456,7 @@
attributes = {
BuildIndependentTargetsInParallel = YES;
LastSwiftUpdateCheck = 0730;
LastUpgradeCheck = 1500;
LastUpgradeCheck = 1510;
ORGANIZATIONNAME = "SwiftKick Mobile";
TargetAttributes = {
86B48AEB1D5A41C900063E2B = {
@@ -556,6 +559,7 @@
22F27951210CE25900273E7F /* CornerRoundingView.swift in Sources */,
86BBA9011D5E040600FE8F16 /* PassthroughWindow.swift in Sources */,
2298C2071EE480D000E2DDC1 /* Animator.swift in Sources */,
22D3B4562B1CEF76002D8665 /* Task+Extensions.swift in Sources */,
86BBA9031D5E040600FE8F16 /* UIViewController+Extensions.swift in Sources */,
228F7DDF2ACF703A006C9644 /* SwiftMessageModifier.swift in Sources */,
224FB69921153B440081D4DE /* CALayer+Extensions.swift in Sources */,
@@ -609,6 +613,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
@@ -655,7 +660,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
@@ -668,6 +673,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
@@ -708,7 +714,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
@@ -732,7 +738,7 @@
GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = YES;
INFOPLIST_FILE = SwiftMessages/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
@@ -767,7 +773,7 @@
GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = YES;
INFOPLIST_FILE = SwiftMessages/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1500"
LastUpgradeVersion = "1510"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
+6 -7
View File
@@ -136,13 +136,12 @@ open class KeyboardTrackingView: UIView {
self.didChange(change: change, userInfo: userInfo)
self.delegate?.keyboardTrackingViewDidChange(change: change, userInfo: userInfo)
}
UIView.beginAnimations(nil, context: nil)
UIView.setAnimationDuration(durationNumber.doubleValue)
UIView.setAnimationCurve(UIView.AnimationCurve(rawValue: curveNumber.intValue)!)
UIView.setAnimationBeginsFromCurrentState(true)
self.superview?.layoutIfNeeded()
UIView.commitAnimations()
CATransaction.commit()
let curve = UIView.AnimationCurve(rawValue: curveNumber.intValue) ?? .easeInOut
let animation = UIViewPropertyAnimator(duration: durationNumber.doubleValue, curve: curve) {
self.updateConstraintsIfNeeded()
self.superview?.layoutIfNeeded()
}
animation.startAnimation()
}
}
+2
View File
@@ -12,6 +12,7 @@ protocol PresenterDelegate: AnimationDelegate {
func hide(presenter: Presenter)
}
@MainActor
class Presenter: NSObject {
// MARK: - API
@@ -77,6 +78,7 @@ class Presenter: NSObject {
// MARK: - Constants
@MainActor
enum PresentationContext {
case viewController(_: Weak<UIViewController>)
case view(_: Weak<UIView>)
+1 -1
View File
@@ -47,7 +47,7 @@ private struct SwiftMessageModifier<Message>: ViewModifier where Message: Messag
content
.onChange(of: message) { _ in
if let message {
let show: (SwiftMessages.Config, UIView) -> Void = swiftMessages?.show(config:view:) ?? SwiftMessages.show(config:view:)
let show: @MainActor (SwiftMessages.Config, UIView) -> Void = swiftMessages?.show(config:view:) ?? SwiftMessages.show(config:view:)
let view = MessageHostingView(message: message)
var config = config ?? swiftMessages?.defaultConfig ?? SwiftMessages.defaultConfig
config.eventListeners.append { event in
+66 -101
View File
@@ -8,6 +8,7 @@
import UIKit
@MainActor
private let globalInstance = SwiftMessages()
/**
@@ -15,6 +16,7 @@ private let globalInstance = SwiftMessages()
It behaves like a queue, only showing one message at a time. Message views that
adopt the `Identifiable` protocol (as `MessageView` does) will have duplicates removed.
*/
@MainActor
open class SwiftMessages {
/**
@@ -396,9 +398,7 @@ open class SwiftMessages {
*/
open func show(config: Config, view: UIView) {
let presenter = Presenter(config: config, view: view, delegate: self)
messageQueue.sync {
enqueue(presenter: presenter)
}
enqueue(presenter: presenter)
}
/**
@@ -425,11 +425,11 @@ open class SwiftMessages {
- Parameter config: The configuration options.
- Parameter viewProvider: A block that returns the view to be displayed.
*/
open func show(config: Config, viewProvider: @escaping ViewProvider) {
DispatchQueue.main.async { [weak self] in
guard let strongSelf = self else { return }
nonisolated open func show(config: Config, viewProvider: @escaping ViewProvider) {
Task { @MainActor [weak self] in
guard let self else { return }
let view = viewProvider()
strongSelf.show(config: config, view: view)
self.show(config: config, view: view)
}
}
@@ -451,9 +451,7 @@ open class SwiftMessages {
Hide the current message being displayed by animating it away.
*/
open func hide(animated: Bool = true) {
messageQueue.sync {
hideCurrent(animated: animated)
}
hideCurrent(animated: animated)
}
/**
@@ -461,12 +459,10 @@ open class SwiftMessages {
clear the message queue.
*/
open func hideAll() {
messageQueue.sync {
queue.removeAll()
delays.removeAll()
counts.removeAll()
hideCurrent()
}
queue.removeAll()
delays.removeAll()
counts.removeAll()
hideCurrent()
}
/**
@@ -476,14 +472,12 @@ open class SwiftMessages {
- Parameter id: The identifier of the message to remove.
*/
open func hide(id: String) {
messageQueue.sync {
if id == _current?.id {
hideCurrent()
}
queue = queue.filter { $0.id != id }
delays.remove(id: id)
counts[id] = nil
if id == _current?.id {
hideCurrent()
}
queue = queue.filter { $0.id != id }
delays.remove(id: id)
counts[id] = nil
}
/**
@@ -492,21 +486,19 @@ open class SwiftMessages {
shown from multiple code paths to ensure that all paths are ready to hide.
*/
open func hideCounted(id: String) {
messageQueue.sync {
if let count = counts[id] {
if count < 2 {
counts[id] = nil
} else {
counts[id] = count - 1
return
}
if let count = counts[id] {
if count < 2 {
counts[id] = nil
} else {
counts[id] = count - 1
return
}
if id == _current?.id {
hideCurrent()
}
queue = queue.filter { $0.id != id }
delays.remove(id: id)
}
if id == _current?.id {
hideCurrent()
}
queue = queue.filter { $0.id != id }
delays.remove(id: id)
}
/**
@@ -538,6 +530,7 @@ open class SwiftMessages {
open var pauseBetweenMessages: TimeInterval = 0.5
/// Type for keeping track of delayed presentations
@MainActor
fileprivate class Delays {
fileprivate func add(presenter: Presenter) {
@@ -563,20 +556,17 @@ open class SwiftMessages {
}
func show(presenter: Presenter) {
messageQueue.sync {
enqueue(presenter: presenter)
}
enqueue(presenter: presenter)
}
fileprivate let messageQueue = DispatchQueue(label: "it.swiftkick.SwiftMessages", attributes: [])
fileprivate var queue: [Presenter] = []
fileprivate var delays = Delays()
fileprivate var counts: [String : Int] = [:]
fileprivate var _current: Presenter? = nil {
didSet {
if oldValue != nil {
let delayTime = DispatchTime.now() + pauseBetweenMessages
messageQueue.asyncAfter(deadline: delayTime) { [weak self] in
Task { [weak self] in
try? await Task.sleep(seconds: self?.pauseBetweenMessages ?? 0)
self?.dequeueNext()
}
}
@@ -598,9 +588,10 @@ open class SwiftMessages {
}
if let delay = presenter.delayShow {
delays.add(presenter: presenter)
messageQueue.asyncAfter(deadline: .now() + delay) { [weak self] in
Task { [weak self] in
try? await Task.sleep(seconds: delay)
// Don't enqueue if the view has been hidden during the delay window.
guard let strongSelf = self, strongSelf.delays.remove(presenter: presenter) else { return }
guard let self, self.delays.remove(presenter: presenter) else { return }
doEnqueue()
}
} else {
@@ -618,26 +609,19 @@ open class SwiftMessages {
// block on animation completion.
self.autohideToken = current
current.showDate = CACurrentMediaTime()
DispatchQueue.main.async { [weak self] in
guard let strongSelf = self else { return }
do {
try current.show { completed in
guard let strongSelf = self else { return }
guard completed else {
strongSelf.messageQueue.sync {
strongSelf.internalHide(presenter: current)
}
return
}
if current === strongSelf.autohideToken {
strongSelf.queueAutoHide()
}
do {
try current.show { [weak self] completed in
guard let self else { return }
guard completed else {
self.internalHide(presenter: current)
return
}
} catch {
strongSelf.messageQueue.sync {
strongSelf._current = nil
if current === self.autohideToken {
self.queueAutoHide()
}
}
} catch {
_current = nil
}
}
@@ -654,16 +638,15 @@ open class SwiftMessages {
guard let current = _current, !current.isHiding else { return }
let action = { [weak self] in
current.hide(animated: animated) { (completed) in
guard completed, let strongSelf = self else { return }
strongSelf.messageQueue.sync {
guard strongSelf._current === current else { return }
strongSelf.counts[current.id] = nil
strongSelf._current = nil
}
guard completed, let self else { return }
guard self._current === current else { return }
self.counts[current.id] = nil
self._current = nil
}
}
let delay = current.delayHide ?? 0
DispatchQueue.main.asyncAfter(deadline: .now() + delay) {
Task {
try? await Task.sleep(seconds: delay)
action()
}
}
@@ -674,18 +657,20 @@ open class SwiftMessages {
guard let current = _current else { return }
autohideToken = current
if let pauseDuration = current.pauseDuration {
let delayTime = DispatchTime.now() + pauseDuration
messageQueue.asyncAfter(deadline: delayTime, execute: {
Task { [weak self] in
try? await Task.sleep(seconds: pauseDuration)
// Make sure we've still got a green light to auto-hide.
if self.autohideToken !== current { return }
guard let self, self.autohideToken !== current else { return }
self.internalHide(presenter: current)
})
}
}
}
deinit {
// Prevent orphaned messages
hideCurrent()
guard let current = _current else { return }
Task { @MainActor [current] in
current.hide(animated: true) { _ in }
}
}
}
@@ -701,11 +686,7 @@ extension SwiftMessages {
- Returns: The view of type `T` if it is currently being shown or hidden.
*/
public func current<T: UIView>() -> T? {
var view: T?
messageQueue.sync {
view = _current?.view as? T
}
return view
_current?.view as? T
}
/**
@@ -715,13 +696,7 @@ extension SwiftMessages {
- Returns: The view with matching id if currently being shown or hidden.
*/
public func current<T: UIView>(id: String) -> T? {
var view: T?
messageQueue.sync {
if let current = _current, current.id == id {
view = current.view as? T
}
}
return view
_current?.id == id ? _current?.view as? T : nil
}
/**
@@ -731,13 +706,7 @@ extension SwiftMessages {
- Returns: The view with matching id if currently queued to be shown.
*/
public func queued<T: UIView>(id: String) -> T? {
var view: T?
messageQueue.sync {
if let queued = queue.first(where: { $0.id == id }) {
view = queued.view as? T
}
}
return view
queue.first { $0.id == id }?.view as? T
}
/**
@@ -759,16 +728,12 @@ extension SwiftMessages {
extension SwiftMessages: PresenterDelegate {
func hide(presenter: Presenter) {
messageQueue.sync {
self.internalHide(presenter: presenter)
}
self.internalHide(presenter: presenter)
}
public func hide(animator: Animator) {
messageQueue.sync {
guard let presenter = self.presenter(forAnimator: animator) else { return }
self.internalHide(presenter: presenter)
}
guard let presenter = self.presenter(forAnimator: animator) else { return }
self.internalHide(presenter: presenter)
}
public func panStarted(animator: Animator) {
@@ -898,7 +863,7 @@ extension SwiftMessages {
globalInstance.show(viewProvider: viewProvider)
}
public static func show(config: Config, viewProvider: @escaping ViewProvider) {
nonisolated public static func show(config: Config, viewProvider: @escaping ViewProvider) {
globalInstance.show(config: config, viewProvider: viewProvider)
}
+15
View File
@@ -0,0 +1,15 @@
//
// Task+Extensions.swift
// SwiftMessages
//
// Created by Timothy Moose on 12/3/23.
// Copyright © 2023 SwiftKick Mobile. All rights reserved.
//
import Foundation
extension Task where Success == Never, Failure == Never {
static func sleep(seconds: TimeInterval) async throws {
try await sleep(nanoseconds: UInt64(seconds * 1_000_000_000))
}
}