From 77b72b6b06a091fa5fec84a95b51ebd9288284d5 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Fri, 25 May 2018 16:51:40 -0400 Subject: [PATCH] Migrate to Swift 4. --- Signal/src/UIApplication+OWS.swift | 8 +++---- .../CallNotificationsAdapter.swift | 4 ++-- ...ExperienceUpgradesPageViewController.swift | 15 +++++++------ .../SafetyNumberConfirmationAlert.swift | 7 ++++++- Signal/src/ViewModels/ThreadViewModel.swift | 21 ++++++++++--------- Signal/src/call/CallService.swift | 12 +++++------ Signal/src/call/SignalCall.swift | 4 ++-- .../call/UserInterface/CallUIAdapter.swift | 6 +++--- .../ExperienceUpgrade.swift | 14 ++++++------- .../ExperienceUpgradeFinder.swift | 9 ++++---- Signal/src/views/AudioProgressView.swift | 14 ++++++------- SignalMessaging/SignalMessaging.h | 3 +++ .../ViewModels/ContactShareViewModel.swift | 1 + SignalMessaging/utils/DisplayableText.swift | 10 ++++----- 14 files changed, 71 insertions(+), 57 deletions(-) diff --git a/Signal/src/UIApplication+OWS.swift b/Signal/src/UIApplication+OWS.swift index 9f0149b9e..88517c397 100644 --- a/Signal/src/UIApplication+OWS.swift +++ b/Signal/src/UIApplication+OWS.swift @@ -4,13 +4,13 @@ import Foundation -extension UIApplication { +@objc public extension UIApplication { - var frontmostViewControllerIgnoringAlerts: UIViewController? { + @objc public var frontmostViewControllerIgnoringAlerts: UIViewController? { return findFrontmostViewController(ignoringAlerts: true) } - var frontmostViewController: UIViewController? { + @objc public var frontmostViewController: UIViewController? { return findFrontmostViewController(ignoringAlerts: false) } @@ -26,7 +26,7 @@ extension UIApplication { return viewController.findFrontmostViewController(ignoringAlerts) } - func openSystemSettings() { + @objc public func openSystemSettings() { openURL(URL(string: UIApplicationOpenSettingsURLString)!) } diff --git a/Signal/src/UserInterface/Notifications/CallNotificationsAdapter.swift b/Signal/src/UserInterface/Notifications/CallNotificationsAdapter.swift index c61ed4c27..7ff028716 100644 --- a/Signal/src/UserInterface/Notifications/CallNotificationsAdapter.swift +++ b/Signal/src/UserInterface/Notifications/CallNotificationsAdapter.swift @@ -1,5 +1,5 @@ // -// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. // import Foundation @@ -8,7 +8,7 @@ import Foundation * Present call related notifications to the user. */ @objc(OWSCallNotificationsAdapter) -class CallNotificationsAdapter: NSObject { +public class CallNotificationsAdapter: NSObject { let TAG = "[CallNotificationsAdapter]" let adaptee: OWSCallNotificationsAdaptee diff --git a/Signal/src/ViewControllers/ExperienceUpgradesPageViewController.swift b/Signal/src/ViewControllers/ExperienceUpgradesPageViewController.swift index bb1a26458..d7df42e52 100644 --- a/Signal/src/ViewControllers/ExperienceUpgradesPageViewController.swift +++ b/Signal/src/ViewControllers/ExperienceUpgradesPageViewController.swift @@ -480,7 +480,8 @@ func setPageControlAppearance() { pageControl.currentPageIndicatorTintColor = UIColor.ows_materialBlue } -class ExperienceUpgradesPageViewController: OWSViewController, UIPageViewControllerDataSource { +@objc +public class ExperienceUpgradesPageViewController: OWSViewController, UIPageViewControllerDataSource { let TAG = "[ExperienceUpgradeViewController]" @@ -494,7 +495,8 @@ class ExperienceUpgradesPageViewController: OWSViewController, UIPageViewControl // MARK: - Initializers - required init(experienceUpgrades: [ExperienceUpgrade]) { + @objc + public required init(experienceUpgrades: [ExperienceUpgrade]) { self.experienceUpgrades = experienceUpgrades setPageControlAppearance() @@ -507,13 +509,14 @@ class ExperienceUpgradesPageViewController: OWSViewController, UIPageViewControl } @available(*, unavailable, message:"unavailable, use initWithExperienceUpgrade instead") - required init?(coder aDecoder: NSCoder) { + @objc + public required init?(coder aDecoder: NSCoder) { fatalError("unimplemented") } // MARK: - View lifecycle - override func viewDidLoad() { + @objc public override func viewDidLoad() { guard let firstViewController = allViewControllers.first else { owsFail("\(TAG) no pages to show.") dismiss(animated: true) @@ -524,7 +527,7 @@ class ExperienceUpgradesPageViewController: OWSViewController, UIPageViewControl self.pageViewController.setViewControllers([ firstViewController ], direction: .forward, animated: false, completion: nil) } - override func loadView() { + @objc public override func loadView() { self.view = UIView.container() view.backgroundColor = UIColor.white @@ -677,7 +680,7 @@ class ExperienceUpgradesPageViewController: OWSViewController, UIPageViewControl allViewControllers.append(viewController) } - override func dismiss(animated flag: Bool, completion: (() -> Void)? = nil) { + @objc public override func dismiss(animated flag: Bool, completion: (() -> Void)? = nil) { // Blocking write before dismiss, to be sure they're marked as complete // before HomeView.didAppear is re-fired. self.editingDBConnection.readWrite { transaction in diff --git a/Signal/src/ViewControllers/SafetyNumberConfirmationAlert.swift b/Signal/src/ViewControllers/SafetyNumberConfirmationAlert.swift index 7eb7742ac..8964ddf24 100644 --- a/Signal/src/ViewControllers/SafetyNumberConfirmationAlert.swift +++ b/Signal/src/ViewControllers/SafetyNumberConfirmationAlert.swift @@ -5,7 +5,8 @@ import Foundation import SignalServiceKit -class SafetyNumberConfirmationAlert: NSObject { +@objc +public class SafetyNumberConfirmationAlert: NSObject { let TAG = "[SafetyNumberConfirmationAlert]" @@ -17,18 +18,22 @@ class SafetyNumberConfirmationAlert: NSObject { self.primaryStorage = OWSPrimaryStorage.shared() } + @objc public class func presentAlertIfNecessary(recipientId: String, confirmationText: String, contactsManager: OWSContactsManager, completion: @escaping (Bool) -> Void) -> Bool { return self.presentAlertIfNecessary(recipientIds: [recipientId], confirmationText: confirmationText, contactsManager: contactsManager, completion: completion, beforePresentationHandler: nil) } + @objc public class func presentAlertIfNecessary(recipientId: String, confirmationText: String, contactsManager: OWSContactsManager, completion: @escaping (Bool) -> Void, beforePresentationHandler: (() -> Void)? = nil) -> Bool { return self.presentAlertIfNecessary(recipientIds: [recipientId], confirmationText: confirmationText, contactsManager: contactsManager, completion: completion, beforePresentationHandler: beforePresentationHandler) } + @objc public class func presentAlertIfNecessary(recipientIds: [String], confirmationText: String, contactsManager: OWSContactsManager, completion: @escaping (Bool) -> Void) -> Bool { return self.presentAlertIfNecessary(recipientIds: recipientIds, confirmationText: confirmationText, contactsManager: contactsManager, completion: completion, beforePresentationHandler: nil) } + @objc public class func presentAlertIfNecessary(recipientIds: [String], confirmationText: String, contactsManager: OWSContactsManager, completion: @escaping (Bool) -> Void, beforePresentationHandler: (() -> Void)? = nil) -> Bool { return SafetyNumberConfirmationAlert(contactsManager: contactsManager).presentIfNecessary(recipientIds: recipientIds, confirmationText: confirmationText, diff --git a/Signal/src/ViewModels/ThreadViewModel.swift b/Signal/src/ViewModels/ThreadViewModel.swift index 33d73e657..50b00f001 100644 --- a/Signal/src/ViewModels/ThreadViewModel.swift +++ b/Signal/src/ViewModels/ThreadViewModel.swift @@ -6,21 +6,22 @@ import Foundation @objc public class ThreadViewModel: NSObject { - let hasUnreadMessages: Bool - let lastMessageDate: Date - let isGroupThread: Bool - let threadRecord: TSThread - let unreadCount: UInt - let contactIdentifier: String? - let name: String - let isMuted: Bool + @objc public let hasUnreadMessages: Bool + @objc public let lastMessageDate: Date + @objc public let isGroupThread: Bool + @objc public let threadRecord: TSThread + @objc public let unreadCount: UInt + @objc public let contactIdentifier: String? + @objc public let name: String + @objc public let isMuted: Bool var isContactThread: Bool { return !isGroupThread } - let lastMessageText: String? + @objc public let lastMessageText: String? - init(thread: TSThread, transaction: YapDatabaseReadTransaction) { + @objc + public init(thread: TSThread, transaction: YapDatabaseReadTransaction) { self.threadRecord = thread self.lastMessageDate = thread.lastMessageDate() self.isGroupThread = thread.isGroupThread() diff --git a/Signal/src/call/CallService.swift b/Signal/src/call/CallService.swift index aac010047..edf23f453 100644 --- a/Signal/src/call/CallService.swift +++ b/Signal/src/call/CallService.swift @@ -71,7 +71,7 @@ import SignalMessaging * --[SS.Hangup]--> */ -enum CallError: Error { +public enum CallError: Error { case providerReset case assertionError(description: String) case disconnected @@ -207,7 +207,7 @@ private class SignalCallData: NSObject { } // This class' state should only be accessed on the main queue. -@objc class CallService: NSObject, CallObserver, PeerConnectionClientDelegate { +@objc public class CallService: NSObject, CallObserver, PeerConnectionClientDelegate { // MARK: - Properties @@ -222,7 +222,7 @@ private class SignalCallData: NSObject { // Exposed by environment.m internal let notificationsAdapter: CallNotificationsAdapter - internal var callUIAdapter: CallUIAdapter! + @objc public var callUIAdapter: CallUIAdapter! // MARK: Class @@ -298,7 +298,7 @@ private class SignalCallData: NSObject { } } - required init(accountManager: AccountManager, contactsManager: OWSContactsManager, messageSender: MessageSender, notificationsAdapter: CallNotificationsAdapter) { + @objc public required init(accountManager: AccountManager, contactsManager: OWSContactsManager, messageSender: MessageSender, notificationsAdapter: CallNotificationsAdapter) { self.accountManager = accountManager self.contactsManager = contactsManager self.messageSender = messageSender @@ -353,7 +353,7 @@ private class SignalCallData: NSObject { /** * Initiate an outgoing call. */ - public func handleOutgoingCall(_ call: SignalCall) -> Promise { + func handleOutgoingCall(_ call: SignalCall) -> Promise { SwiftAssertIsOnMainThread(#function) guard self.call == nil else { @@ -938,7 +938,7 @@ private class SignalCallData: NSObject { * * Used by notification actions which can't serialize a call object. */ - public func handleAnswerCall(localId: UUID) { + @objc public func handleAnswerCall(localId: UUID) { SwiftAssertIsOnMainThread(#function) guard let call = self.call else { diff --git a/Signal/src/call/SignalCall.swift b/Signal/src/call/SignalCall.swift index 909030a3f..d38bd1dff 100644 --- a/Signal/src/call/SignalCall.swift +++ b/Signal/src/call/SignalCall.swift @@ -5,7 +5,7 @@ import Foundation import SignalServiceKit -enum CallState: String { +public enum CallState: String { case idle case dialing case answering @@ -37,7 +37,7 @@ protocol CallObserver: class { * * This class' state should only be accessed on the main queue. */ -@objc class SignalCall: NSObject { +@objc public class SignalCall: NSObject { let TAG = "[SignalCall]" diff --git a/Signal/src/call/UserInterface/CallUIAdapter.swift b/Signal/src/call/UserInterface/CallUIAdapter.swift index 67865be3b..45196f572 100644 --- a/Signal/src/call/UserInterface/CallUIAdapter.swift +++ b/Signal/src/call/UserInterface/CallUIAdapter.swift @@ -82,7 +82,7 @@ extension CallUIAdaptee { * Notify the user of call related activities. * Driven by either a CallKit or System notifications adaptee */ -@objc class CallUIAdapter: NSObject, CallServiceObserver { +@objc public class CallUIAdapter: NSObject, CallServiceObserver { let TAG = "[CallUIAdapter]" private let adaptee: CallUIAdaptee @@ -90,7 +90,7 @@ extension CallUIAdaptee { internal let audioService: CallAudioService internal let callService: CallService - required init(callService: CallService, contactsManager: OWSContactsManager, notificationsAdapter: CallNotificationsAdapter) { + public required init(callService: CallService, contactsManager: OWSContactsManager, notificationsAdapter: CallNotificationsAdapter) { SwiftAssertIsOnMainThread(#function) self.contactsManager = contactsManager @@ -155,7 +155,7 @@ extension CallUIAdaptee { return call } - internal func answerCall(localId: UUID) { + @objc public func answerCall(localId: UUID) { SwiftAssertIsOnMainThread(#function) adaptee.answerCall(localId: localId) diff --git a/Signal/src/environment/ExperienceUpgrades/ExperienceUpgrade.swift b/Signal/src/environment/ExperienceUpgrades/ExperienceUpgrade.swift index d3e5735bc..345d82d68 100644 --- a/Signal/src/environment/ExperienceUpgrades/ExperienceUpgrade.swift +++ b/Signal/src/environment/ExperienceUpgrades/ExperienceUpgrade.swift @@ -1,24 +1,24 @@ // -// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. // import Foundation import SignalServiceKit import SignalMessaging -class ExperienceUpgrade: TSYapDatabaseObject { +@objc public class ExperienceUpgrade: TSYapDatabaseObject { let title: String let body: String let image: UIImage? - required init(uniqueId: String, title: String, body: String, image: UIImage) { + @objc public required init(uniqueId: String, title: String, body: String, image: UIImage) { self.title = title self.body = body self.image = image super.init(uniqueId: uniqueId) } - override required init(uniqueId: String?) { + @objc public override required init(uniqueId: String?) { // This is the unfortunate seam between strict swift and fast-and-loose objc // we can't leave these properties nil, since we really "don't know" that the superclass // will assign them. @@ -28,7 +28,7 @@ class ExperienceUpgrade: TSYapDatabaseObject { super.init(uniqueId: uniqueId) } - required init!(coder: NSCoder) { + @objc public required init!(coder: NSCoder) { // This is the unfortunate seam between strict swift and fast-and-loose objc // we can't leave these properties nil, since we really "don't know" that the superclass // will assign them. @@ -38,7 +38,7 @@ class ExperienceUpgrade: TSYapDatabaseObject { super.init(coder: coder) } - required init(dictionary dictionaryValue: [AnyHashable : Any]!) throws { + @objc public required init(dictionary dictionaryValue: [AnyHashable: Any]!) throws { // This is the unfortunate seam between strict swift and fast-and-loose objc // we can't leave these properties nil, since we really "don't know" that the superclass // will assign them. @@ -48,7 +48,7 @@ class ExperienceUpgrade: TSYapDatabaseObject { try super.init(dictionary: dictionaryValue) } - override class func storageBehaviorForProperty(withKey propertyKey: String) -> MTLPropertyStorage { + @objc public override class func storageBehaviorForProperty(withKey propertyKey: String) -> MTLPropertyStorage { // These exist in a hardcoded set - no need to save them, plus it allows us to // update copy/image down the line if there was a typo and we want to re-expose // these models in a "change log" archive. diff --git a/Signal/src/environment/ExperienceUpgrades/ExperienceUpgradeFinder.swift b/Signal/src/environment/ExperienceUpgrades/ExperienceUpgradeFinder.swift index edf3bc739..7653b79f9 100644 --- a/Signal/src/environment/ExperienceUpgrades/ExperienceUpgradeFinder.swift +++ b/Signal/src/environment/ExperienceUpgrades/ExperienceUpgradeFinder.swift @@ -44,25 +44,26 @@ class ExperienceUpgradeFinder: NSObject { return ExperienceUpgrade(uniqueId: ExperienceUpgradeId.introducingProfiles.rawValue, title: NSLocalizedString("UPGRADE_EXPERIENCE_INTRODUCING_PROFILES_TITLE", comment: "Header for upgrade experience"), body: NSLocalizedString("UPGRADE_EXPERIENCE_INTRODUCING_PROFILES_DESCRIPTION", comment: "Description of new profile feature for upgrading (existing) users"), - image:#imageLiteral(resourceName: "introductory_splash_profile")) + image: #imageLiteral(resourceName: "introductory_splash_profile")) } var introducingReadReceipts: ExperienceUpgrade { return ExperienceUpgrade(uniqueId: ExperienceUpgradeId.introducingReadReceipts.rawValue, title: NSLocalizedString("UPGRADE_EXPERIENCE_INTRODUCING_READ_RECEIPTS_TITLE", comment: "Header for upgrade experience"), body: NSLocalizedString("UPGRADE_EXPERIENCE_INTRODUCING_READ_RECEIPTS_DESCRIPTION", comment: "Description of new profile feature for upgrading (existing) users"), - image:#imageLiteral(resourceName: "introductory_splash_read_receipts")) + image: #imageLiteral(resourceName: "introductory_splash_read_receipts")) } var configurableNotificationAudio: ExperienceUpgrade { return ExperienceUpgrade(uniqueId: ExperienceUpgradeId.introducingCustomNotificationAudio.rawValue, title: NSLocalizedString("UPGRADE_EXPERIENCE_INTRODUCING_NOTIFICATION_AUDIO_TITLE", comment: "Header for upgrade experience"), body: NSLocalizedString("UPGRADE_EXPERIENCE_INTRODUCING_NOTIFICATION_AUDIO_DESCRIPTION", comment: "Description for notification audio customization"), - image:#imageLiteral(resourceName: "introductory_splash_custom_audio")) + image: #imageLiteral(resourceName: "introductory_splash_custom_audio")) } // Keep these ordered by increasing uniqueId. - private var allExperienceUpgrades: [ExperienceUpgrade] { + @objc + public var allExperienceUpgrades: [ExperienceUpgrade] { return [ // Disable old experience upgrades. Most people have seen them by now, and accomodating multiple makes layout harder. // Note if we ever want to show multiple experience upgrades again diff --git a/Signal/src/views/AudioProgressView.swift b/Signal/src/views/AudioProgressView.swift index d897e5e98..2d3b2e5da 100644 --- a/Signal/src/views/AudioProgressView.swift +++ b/Signal/src/views/AudioProgressView.swift @@ -5,9 +5,9 @@ import UIKit import SignalServiceKit -@objc class AudioProgressView: UIView { +@objc public class AudioProgressView: UIView { - override var bounds: CGRect { + @objc public override var bounds: CGRect { didSet { if oldValue != bounds { updateSubviews() @@ -15,7 +15,7 @@ import SignalServiceKit } } - override var frame: CGRect { + @objc public override var frame: CGRect { didSet { if oldValue != frame { updateSubviews() @@ -23,13 +23,13 @@ import SignalServiceKit } } - var horizontalBarColor = UIColor.black { + @objc public var horizontalBarColor = UIColor.black { didSet { updateContent() } } - var progressColor = UIColor.blue { + @objc public var progressColor = UIColor.blue { didSet { updateContent() } @@ -38,7 +38,7 @@ import SignalServiceKit private let horizontalBarLayer: CAShapeLayer private let progressLayer: CAShapeLayer - var progress: CGFloat = 0 { + @objc public var progress: CGFloat = 0 { didSet { if oldValue != progress { updateContent() @@ -47,7 +47,7 @@ import SignalServiceKit } @available(*, unavailable, message:"use other constructor instead.") - required init?(coder aDecoder: NSCoder) { + @objc public required init?(coder aDecoder: NSCoder) { fatalError("\(#function) is unimplemented.") } diff --git a/SignalMessaging/SignalMessaging.h b/SignalMessaging/SignalMessaging.h index 976e86006..c59c7c0eb 100644 --- a/SignalMessaging/SignalMessaging.h +++ b/SignalMessaging/SignalMessaging.h @@ -27,6 +27,7 @@ FOUNDATION_EXPORT const unsigned char SignalMessagingVersionString[]; #import #import #import +#import #import #import #import @@ -37,10 +38,12 @@ FOUNDATION_EXPORT const unsigned char SignalMessagingVersionString[]; #import #import #import +#import #import #import #import #import +#import #import #import #import diff --git a/SignalMessaging/ViewModels/ContactShareViewModel.swift b/SignalMessaging/ViewModels/ContactShareViewModel.swift index 24350735a..a6c313919 100644 --- a/SignalMessaging/ViewModels/ContactShareViewModel.swift +++ b/SignalMessaging/ViewModels/ContactShareViewModel.swift @@ -39,6 +39,7 @@ public class ContactShareViewModel: NSObject { self.avatarImageData = avatarImageData } + @objc public convenience init(contactShareRecord: OWSContact, transaction: YapDatabaseReadTransaction) { if let avatarAttachment = contactShareRecord.avatarAttachment(with: transaction) as? TSAttachmentStream { self.init(contactShareRecord: contactShareRecord, avatarImageData: avatarAttachment.validStillImageData()) diff --git a/SignalMessaging/utils/DisplayableText.swift b/SignalMessaging/utils/DisplayableText.swift index c5bbb26eb..265322126 100644 --- a/SignalMessaging/utils/DisplayableText.swift +++ b/SignalMessaging/utils/DisplayableText.swift @@ -152,10 +152,10 @@ extension String { static let TAG = "[DisplayableText]" - public let fullText: String - public let displayText: String - public let isTextTruncated: Bool - public let jumbomojiCount: UInt + @objc public let fullText: String + @objc public let displayText: String + @objc public let isTextTruncated: Bool + @objc public let jumbomojiCount: UInt static let kMaxJumbomojiCount: UInt = 5 // This value is a bit arbitrary since we don't need to be 100% correct about @@ -165,7 +165,7 @@ extension String { // MARK: Initializers - init(fullText: String, displayText: String, isTextTruncated: Bool) { + @objc public init(fullText: String, displayText: String, isTextTruncated: Bool) { self.fullText = fullText self.displayText = displayText self.isTextTruncated = isTextTruncated