From a684248d4fbed1ec48967ffacef583c0bd27ead7 Mon Sep 17 00:00:00 2001 From: dfsm Date: Sat, 7 Aug 2021 13:29:13 +1000 Subject: [PATCH 1/3] Working additional option "Full reset" --- App/Main/AppDelegate.swift | 34 +++++++++++---- App/Settings/Settings.plist | 8 +++- .../Settings/SettingsViewController.swift | 43 +++++++++++++------ 3 files changed, 64 insertions(+), 21 deletions(-) diff --git a/App/Main/AppDelegate.swift b/App/Main/AppDelegate.swift index 5f50afa5a..55feaf7e9 100644 --- a/App/Main/AppDelegate.swift +++ b/App/Main/AppDelegate.swift @@ -59,6 +59,9 @@ final class AppDelegate: UIResponder, UIApplicationDelegate { if ForumsClient.shared.isLoggedIn { setRootViewController(rootViewControllerStack.rootViewController, animated: false, completion: nil) } else { + if loginViewController == nil { + newLoginController() + } setRootViewController(loginViewController.enclosingNavigationController, animated: false, completion: nil) } @@ -170,23 +173,29 @@ final class AppDelegate: UIResponder, UIApplicationDelegate { return router.route(route) } + func fullReset() { + UserDefaults.standard.removeAllObjectsInMainBundleDomain() + emptyCache() + dataStore.deleteStoreAndReset() + logOut() + } + func logOut() { - // Logging out doubles as an "empty cache" button. let cookieJar = HTTPCookieStorage.shared for cookie in cookieJar.cookies ?? [] { cookieJar.deleteCookie(cookie) } - UserDefaults.standard.removeAllObjectsInMainBundleDomain() - emptyCache() - - // Do this after resetting settings so that it gets the default baseURL. + updateClientBaseURL() + if loginViewController == nil { + newLoginController() + } + setRootViewController(loginViewController.enclosingNavigationController, animated: true) { [weak self] in self?._rootViewControllerStack = nil + self?.urlRouter = nil - - self?.dataStore.deleteStoreAndReset() } } @@ -255,7 +264,7 @@ final class AppDelegate: UIResponder, UIApplicationDelegate { return stack } - private lazy var loginViewController: LoginViewController! = { + private func createLoginViewController() -> LoginViewController! { let loginVC = LoginViewController.newFromStoryboard() loginVC.completionBlock = { [weak self] (login) in guard let self = self else { return } @@ -266,7 +275,16 @@ final class AppDelegate: UIResponder, UIApplicationDelegate { }) } return loginVC + } + + private lazy var loginViewController : LoginViewController! = { + return self.createLoginViewController() }() + + private func newLoginController() { + loginViewController = createLoginViewController() + } + } private extension AppDelegate { diff --git a/App/Settings/Settings.plist b/App/Settings/Settings.plist index 3df71a6ef..c04b4c22f 100644 --- a/App/Settings/Settings.plist +++ b/App/Settings/Settings.plist @@ -8,7 +8,7 @@ TitleKey username Explanation - Logging out erases all cached forums, threads, and posts. + Full reset erases all cached forums, threads, and posts. Action ShowProfile Settings @@ -25,6 +25,12 @@ Action EmptyCache + + Title + Full Reset + Action + FullReset + diff --git a/App/View Controllers/Settings/SettingsViewController.swift b/App/View Controllers/Settings/SettingsViewController.swift index 69350a699..5c8a7d682 100644 --- a/App/View Controllers/Settings/SettingsViewController.swift +++ b/App/View Controllers/Settings/SettingsViewController.swift @@ -370,26 +370,45 @@ final class SettingsViewController: TableViewController { defer { tableView.deselectRow(at: indexPath, animated: true) } let setting = self.setting(at: indexPath) + let settingTitle = setting["Title"] as? String + switch (setting["Action"] as? String, setting["ViewController"] as? String) { case ("LogOut"?, _): let alert = UIAlertController(title: nil, message: nil, preferredStyle: .alert) - alert.title = "Log Out" + alert.title = settingTitle ?? "Log Out" alert.message = "Are you sure you want to log out?" alert.addCancelActionWithHandler(nil) - alert.addActionWithTitle("Log Out", handler: { AppDelegate.instance.logOut() }) + alert.addActionWithTitle(settingTitle ?? "Log Out", handler: { + AppDelegate.instance.logOut() + }) present(alert, animated: true) case ("EmptyCache"?, _): - let usageBefore = URLCache.shared.currentDiskUsage - AppDelegate.instance.emptyCache(); - let usageAfter = URLCache.shared.currentDiskUsage - let message = "You cleared up \((usageBefore - usageAfter)/(1024*1024)) megabytes! Great job, go hog wild!!" - let alertController = UIAlertController(title: "Cache Cleared", message: message, preferredStyle: .alert) - let okAction = UIAlertAction(title: "OK", style: .default) { action in - self.dismiss(animated: true) - } - alertController.addAction(okAction) - self.present(alertController, animated: true) + let alert = UIAlertController(title: nil, message: nil, preferredStyle: .alert) + alert.title = settingTitle ?? "Empty Cache" + alert.message = "Are you sure you want to empty the cache?" + alert.addCancelActionWithHandler(nil) + alert.addActionWithTitle(settingTitle ?? "Empty Cache", handler: { + AppDelegate.instance.emptyCache(); + let message = "You emptied the cache! Great job, go hog wild!!" + let alertController = UIAlertController(title: "Cache Cleared", message: message, preferredStyle: .alert) + let okAction = UIAlertAction(title: "OK", style: .default) { action in + self.dismiss(animated: true) + } + alertController.addAction(okAction) + self.present(alertController, animated: true) + }) + present(alert, animated: true) + + case ("FullReset"?, _): + let alert = UIAlertController(title: nil, message: nil, preferredStyle: .alert) + alert.title = settingTitle ?? "Full Reset" + alert.message = "This will reset all settings, clear all caches and log out. Are you sure?" + alert.addCancelActionWithHandler(nil) + alert.addActionWithTitle(settingTitle ?? "Full Reset", handler: { + AppDelegate.instance.fullReset() + }) + present(alert, animated: true) case ("GoToAwfulThread"?, _): guard let threadID = setting["ThreadID"] as? String else { From fb63077026edd8a9515566018370322f132bb0d5 Mon Sep 17 00:00:00 2001 From: dfsm Date: Sat, 7 Aug 2021 14:01:27 +1000 Subject: [PATCH 2/3] Log out option no longer clears cache - Log out option will now only delete the cookie and present the login screen - New option added "Full reset". This performs the actions Log Out did previously - Removed all traces of the MiniOnePassword package. This is no longer required as iOS supports 1password for login fields - Updated Login.storyboard to set fields as Username and Password. This allows iOS to present password manager options --- .../onepassword-button.imageset/Contents.json | 56 ------ .../onepassword-button-light.png | Bin 701 -> 0 bytes .../onepassword-button-light@2x.png | Bin 1734 -> 0 bytes .../onepassword-button-light@3x.png | Bin 2821 -> 0 bytes .../onepassword-button.png | Bin 965 -> 0 bytes .../onepassword-button@2x.png | Bin 1827 -> 0 bytes .../onepassword-button@3x.png | Bin 2993 -> 0 bytes App/Templates/Acknowledgements.html.stencil | 28 --- App/View Controllers/Login.storyboard | 29 +-- .../LoginViewController.swift | 34 ---- Awful.xcworkspace/contents.xcworkspacedata | 3 - MiniOnePassword/.gitignore | 4 - .../xcschemes/MiniOnePassword.xcscheme | 67 ------- MiniOnePassword/Package.swift | 17 -- MiniOnePassword/README.md | 3 - .../MiniOnePassword/MiniOnePassword.swift | 173 ------------------ Xcode/Awful.xcodeproj/project.pbxproj | 7 - 17 files changed, 6 insertions(+), 415 deletions(-) delete mode 100644 App/Resources/Assets.xcassets/onepassword-button.imageset/Contents.json delete mode 100644 App/Resources/Assets.xcassets/onepassword-button.imageset/onepassword-button-light.png delete mode 100644 App/Resources/Assets.xcassets/onepassword-button.imageset/onepassword-button-light@2x.png delete mode 100644 App/Resources/Assets.xcassets/onepassword-button.imageset/onepassword-button-light@3x.png delete mode 100644 App/Resources/Assets.xcassets/onepassword-button.imageset/onepassword-button.png delete mode 100644 App/Resources/Assets.xcassets/onepassword-button.imageset/onepassword-button@2x.png delete mode 100644 App/Resources/Assets.xcassets/onepassword-button.imageset/onepassword-button@3x.png delete mode 100644 MiniOnePassword/.gitignore delete mode 100644 MiniOnePassword/.swiftpm/xcode/xcshareddata/xcschemes/MiniOnePassword.xcscheme delete mode 100644 MiniOnePassword/Package.swift delete mode 100644 MiniOnePassword/README.md delete mode 100644 MiniOnePassword/Sources/MiniOnePassword/MiniOnePassword.swift diff --git a/App/Resources/Assets.xcassets/onepassword-button.imageset/Contents.json b/App/Resources/Assets.xcassets/onepassword-button.imageset/Contents.json deleted file mode 100644 index ef1c4c57a..000000000 --- a/App/Resources/Assets.xcassets/onepassword-button.imageset/Contents.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "images" : [ - { - "filename" : "onepassword-button.png", - "idiom" : "universal", - "scale" : "1x" - }, - { - "appearances" : [ - { - "appearance" : "luminosity", - "value" : "dark" - } - ], - "filename" : "onepassword-button-light.png", - "idiom" : "universal", - "scale" : "1x" - }, - { - "filename" : "onepassword-button@2x.png", - "idiom" : "universal", - "scale" : "2x" - }, - { - "appearances" : [ - { - "appearance" : "luminosity", - "value" : "dark" - } - ], - "filename" : "onepassword-button-light@2x.png", - "idiom" : "universal", - "scale" : "2x" - }, - { - "filename" : "onepassword-button@3x.png", - "idiom" : "universal", - "scale" : "3x" - }, - { - "appearances" : [ - { - "appearance" : "luminosity", - "value" : "dark" - } - ], - "filename" : "onepassword-button-light@3x.png", - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/App/Resources/Assets.xcassets/onepassword-button.imageset/onepassword-button-light.png b/App/Resources/Assets.xcassets/onepassword-button.imageset/onepassword-button-light.png deleted file mode 100644 index 6f4b019ea5bce5992d46d7c619b04426f286313b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 701 zcmV;u0z&Px%cS%G+R7efIR=sW%K@8qWbg58?awxzR)F{;O1_-L~a}l)g06YK!0cCg_OL_M0S@%@(q#EZ?GJIVMqJjrB-MnSs%{R0{~1~ z1mKGQ1$NcS_`4N95OO?dSJl`@Uk2$@zn+fDy>A_6t^d zb?T%z2)kVaVp2Kl%!*ym5T% zA`QPq;hbrzEw*L9s+-V{0qmPUn)C?9M>W!CKCUFEQ-ys)nCqB4r9Giz1M|mjmtanD z)eT3;@P_WHf(K zCFZBYkj*!L^aY$5{%8H!z92<_nvv~k`hRbug0Tdc(W|e3t@9c48uFXZXXzqz)AJd@ zNJo&VaRfe7)MRP}Ypg-emo*4$5!NI{&TC(T6yX&S&Y-$7Fpcu)>&D;#CdrxzmoIDH jtF4HiqauFQR1yCH=ZRc4>1ULp00000NkvXXu0mjf)-Xc> diff --git a/App/Resources/Assets.xcassets/onepassword-button.imageset/onepassword-button-light@2x.png b/App/Resources/Assets.xcassets/onepassword-button.imageset/onepassword-button-light@2x.png deleted file mode 100644 index 2257425a68d89a63a1c9c8c12906a644a8c63e2c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1734 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 R&L98)002ovPDHLkV1ivsZ)^Yn diff --git a/App/Resources/Assets.xcassets/onepassword-button.imageset/onepassword-button@3x.png b/App/Resources/Assets.xcassets/onepassword-button.imageset/onepassword-button@3x.png deleted file mode 100644 index 749ff2fe3f9e707d0d2355a1a3c9a16b8803e2eb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2993 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 diff --git a/App/Templates/Acknowledgements.html.stencil b/App/Templates/Acknowledgements.html.stencil index 197b0752e..14550a4bf 100644 --- a/App/Templates/Acknowledgements.html.stencil +++ b/App/Templates/Acknowledgements.html.stencil @@ -146,34 +146,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -
-
-

1Password App Extension

- github.com/AgileBits/onepassword-app-extension -
- -
-Copyright (c) 2014 AgileBits Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-
-

PromiseKit

diff --git a/App/View Controllers/Login.storyboard b/App/View Controllers/Login.storyboard index ba25e514c..fb657323c 100644 --- a/App/View Controllers/Login.storyboard +++ b/App/View Controllers/Login.storyboard @@ -1,9 +1,10 @@ - + - + + @@ -42,7 +43,7 @@ - + @@ -63,27 +64,14 @@ - + - - + @@ -96,10 +84,7 @@ - - - @@ -207,11 +192,9 @@ - - diff --git a/App/View Controllers/LoginViewController.swift b/App/View Controllers/LoginViewController.swift index 4664aa84b..400d790be 100644 --- a/App/View Controllers/LoginViewController.swift +++ b/App/View Controllers/LoginViewController.swift @@ -3,7 +3,6 @@ // Copyright 2014 Awful Contributors. CC BY-NC-SA 3.0 US https://github.com/Awful/Awful.app import AwfulCore -import MiniOnePassword import UIKit private let Log = Logger.get() @@ -23,9 +22,6 @@ class LoginViewController: ViewController { @IBOutlet weak var activityIndicator: UIActivityIndicatorView! @IBOutlet private var consentToTermsTextView: UITextView! - @IBOutlet weak var onePasswordButton: UIButton! - @IBOutlet var onePasswordUnavailableConstraints: [NSLayoutConstraint]! - fileprivate enum State { case awaitingUsername case awaitingPassword @@ -72,13 +68,6 @@ class LoginViewController: ViewController { // Can't set this in the storyboard for some reason. nextBarButtonItem.isEnabled = false - - onePasswordButton.setImage(UIImage(named: "onepassword-button"), for: .normal) - - if !OnePassword.isAvailable { - onePasswordButton.removeFromSuperview() - view.addConstraints(onePasswordUnavailableConstraints) - } consentToTermsTextView.attributedText = { let format = NSAttributedString(string: LocalizedString("login.consent-to-terms.full-text")) @@ -129,29 +118,6 @@ class LoginViewController: ViewController { } } - @IBAction func didTapOnePassword(_ sender: UIButton) { - view.endEditing(true) - - OnePassword.findLogin( - urlString: "forums.somethingawful.com", - presentingViewController: self, - sender: .view(sender), - completion: { result in - switch result { - case let .success(loginInfo): - self.usernameTextField.text = loginInfo.username - self.passwordTextField.text = loginInfo.password - self.state = .canAttemptLogin - - case .failure(.userCancelled): - break - - case let .failure(error): - Log.e("1Password extension failed: \(error)") - } - }) - } - fileprivate func attemptToLogIn() { assert(state == .canAttemptLogin, "unexpected state") state = .attemptingLogin diff --git a/Awful.xcworkspace/contents.xcworkspacedata b/Awful.xcworkspace/contents.xcworkspacedata index 590e507c0..ef7f611ec 100644 --- a/Awful.xcworkspace/contents.xcworkspacedata +++ b/Awful.xcworkspace/contents.xcworkspacedata @@ -19,9 +19,6 @@ - - diff --git a/MiniOnePassword/.gitignore b/MiniOnePassword/.gitignore deleted file mode 100644 index 02c087533..000000000 --- a/MiniOnePassword/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -.DS_Store -/.build -/Packages -/*.xcodeproj diff --git a/MiniOnePassword/.swiftpm/xcode/xcshareddata/xcschemes/MiniOnePassword.xcscheme b/MiniOnePassword/.swiftpm/xcode/xcshareddata/xcschemes/MiniOnePassword.xcscheme deleted file mode 100644 index c7a13b67c..000000000 --- a/MiniOnePassword/.swiftpm/xcode/xcshareddata/xcschemes/MiniOnePassword.xcscheme +++ /dev/null @@ -1,67 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/MiniOnePassword/Package.swift b/MiniOnePassword/Package.swift deleted file mode 100644 index c214b94c8..000000000 --- a/MiniOnePassword/Package.swift +++ /dev/null @@ -1,17 +0,0 @@ -// swift-tools-version:5.1 - -import PackageDescription - -let package = Package( - name: "MiniOnePassword", - products: [ - .library( - name: "MiniOnePassword", - targets: ["MiniOnePassword"]), - ], - targets: [ - .target( - name: "MiniOnePassword", - dependencies: []), - ] -) diff --git a/MiniOnePassword/README.md b/MiniOnePassword/README.md deleted file mode 100644 index 9457f34e3..000000000 --- a/MiniOnePassword/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# MiniOnePassword - -There's an [official 1Password library for loading passwords](https://github.com/agilebits/onepassword-app-extension) but it's way more than we need and has historically been unhelpfully packaged. MiniOnePassword just does the bits we need and is less of a pain to deal with. diff --git a/MiniOnePassword/Sources/MiniOnePassword/MiniOnePassword.swift b/MiniOnePassword/Sources/MiniOnePassword/MiniOnePassword.swift deleted file mode 100644 index 1c51b20fe..000000000 --- a/MiniOnePassword/Sources/MiniOnePassword/MiniOnePassword.swift +++ /dev/null @@ -1,173 +0,0 @@ -import CoreServices -import UIKit - -/* - Roughly ported from https://github.com/agilebits/onepassword-app-extension, which is unusable from UIKit for Mac because of its references to `UIWebView`. This code is not meaningfully different from that code, so here's its license and you should adhere to it: - - Copyright (c) 2014 AgileBits Inc. - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - */ - -/// Asks 1Password (or other compliant password managers) to supply a username and password. -public enum OnePassword { - - /// Checks if the 1Password extension (or similar) is available. You might hide the 1Password button if this returns `false`. - public static var isAvailable: Bool { - return UIApplication.shared.canOpenURL(URL(string: "org-appextension-feature-password-management://")!) - } - - /** - Finds the first available login among all logins matching the domain of `urlString` by using the system share sheet. - - For example, passing a `urlString` of `https://example.com` will match logins for both `spiffy.example.com` and `excellent.example.com`. - - 1Password will show a "Show All Logins" button if no logins are found matching `urlString`. - - - Parameter urlString: A domain filter for the logins shown by 1Password. Only the domain is considered, and subdomains are included. Passing `https://example.com` will match logins for all of `example.com`, `spiffy.example.com`, and `excellent.example.com`. - - Parameter sender: Where the share sheet popover should point. Note that `.none` is likely to crash on non-phone devices. - - Parameter completion: A block to call after attempting to find login info. The block is called on the main queue. - - - Note: Must be called on the main queue. - */ - public static func findLogin( - urlString: String, - presentingViewController: UIViewController, - sender: Sender, - completion: @escaping FindLoginCompletion) - { - guard isAvailable else { - return completion(.failure(.cannotOpenExtensionURL)) - } - - let item: [String: Any] = ["version_number": 184, "url_string": urlString] - let itemProvider = NSItemProvider(item: item as NSDictionary, typeIdentifier: "org.appextension.find-login-action") - let extensionItem = NSExtensionItem() - extensionItem.attachments = [itemProvider] - let activityVC = UIActivityViewController(activityItems: [extensionItem], applicationActivities: nil) - - activityVC.completionWithItemsHandler = { activityType, completed, returnedItems, activityError in - guard let returnedItem = returnedItems?.first else { - let error = activityError.map { OnePasswordError.activityError($0) } - ?? .userCancelled - return completion(.failure(error)) - } - - processReturnedItem(returnedItem, completion: completion) - } - - presentingViewController.present(activityVC, animated: true) - - switch sender { - case let .barButton(button): - activityVC.popoverPresentationController?.barButtonItem = button - - case let .view(view): - activityVC.popoverPresentationController?.sourceView = view - activityVC.popoverPresentationController?.sourceRect = view.bounds - - case .none where UIDevice.current.userInterfaceIdiom != .phone: - print("The sender parameter passed to OnePassword.findLogin(…) is likely required to not be .none; if you see a UIKit exception shortly, this might be why") - - case .none: - break // ok - } - } - - private static func processReturnedItem( - _ returnedItem: Any, - completion: @escaping FindLoginCompletion) - { - guard - let extensionItem = returnedItem as? NSExtensionItem, - let itemProvider = extensionItem.attachments?.first, - itemProvider.hasItemConformingToTypeIdentifier(kUTTypePropertyList as String) else - { - return completion(.failure(.noPropertyListAttachment)) - } - - itemProvider.loadItem(forTypeIdentifier: kUTTypePropertyList as String, options: nil, completionHandler: { - rawItemDictionary, itemProviderError in - DispatchQueue.main.async { - guard let itemDictionary = rawItemDictionary as? [String: Any] else { - return completion(.failure(.missingPropertyList(itemProviderError))) - } - - guard - let username = itemDictionary["username"] as? String, - let password = itemDictionary["password"] as? String else - { - return completion(.failure(.missingKeyInPropertyListAttachment)) - } - - completion(.success(.init(username: username, password: password))) - } - }) - } - - /// - Seealso: `findLogin(urlString:presentingViewController:sender:completion:)`. - public typealias FindLoginCompletion = (Result) -> Void - - /** - Login info provided by 1Password. Use this to fill in your login form automatically for the user. - - - Seealso: `findLogin(urlString:presentingViewController:sender:completion:)`. - */ - public struct LoginInfo { - public let username: String - public let password: String - } - - /** - Where the share sheet popover should point. - - - Seealso: `findLogin(urlString:presentingViewController:sender:completion:)`. - */ - public enum Sender { - case barButton(UIBarButtonItem) - case view(UIView) - - /// Will likely crash with a UIKit exception on non-phones. - case none - } -} - -public enum OnePasswordError: Error { - - /// The system share sheet failed for some reason, and it wasn't because the user cancelled (that's `.userCancelled`). - case activityError(Error) - - /// No app seems to be installed that acts as a password manager. - case cannotOpenExtensionURL - - /// The password manager's provided login was missing either `username` or `password`. - case missingKeyInPropertyListAttachment - - /// The password manager did not return a dictionary property list. - case missingPropertyList(Error?) - - /// The share provider did not include any attachments. - case noAttachments - - /// The share provider did not include a property list among the attachments. - case noPropertyListAttachment - - /// The user decided not to find a login in their password manager. - case userCancelled -} diff --git a/Xcode/Awful.xcodeproj/project.pbxproj b/Xcode/Awful.xcodeproj/project.pbxproj index 6f3f83a28..cab4bed37 100644 --- a/Xcode/Awful.xcodeproj/project.pbxproj +++ b/Xcode/Awful.xcodeproj/project.pbxproj @@ -272,7 +272,6 @@ 1CA45D961F2C19AA005BEEC5 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 1CA45D951F2C19AA005BEEC5 /* Localizable.strings */; }; 1CA56FEB1A009BDF009A91AE /* PotentiallyObjectionableTexts.plist in Resources */ = {isa = PBXBuildFile; fileRef = 1CA56FEA1A009BDF009A91AE /* PotentiallyObjectionableTexts.plist */; }; 1CA887B01F40AE1A0059FEEC /* User+Presentation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CA887AF1F40AE1A0059FEEC /* User+Presentation.swift */; }; - 1CAEA24322D14FFE009CB9EB /* MiniOnePassword in Frameworks */ = {isa = PBXBuildFile; productRef = 1CAEA24222D14FFE009CB9EB /* MiniOnePassword */; }; 1CAF2372250C8CE400033F61 /* Nuke in Frameworks */ = {isa = PBXBuildFile; productRef = 1CAF2371250C8CE400033F61 /* Nuke */; }; 1CB15BCF1A9CEB8800176E73 /* Themes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CB15BCE1A9CEB8800176E73 /* Themes.swift */; }; 1CB15BEE1A9D33F600176E73 /* URLMenuPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CB15BED1A9D33F600176E73 /* URLMenuPresenter.swift */; }; @@ -1051,7 +1050,6 @@ 1C453F282338457A007AC6CD /* Stencil in Frameworks */, 1CD72E79265CA0D500FF3BF4 /* AwfulCore in Frameworks */, 1C5C2B8D22D195BF00EA5A80 /* ImgurAnonymousAPI in Frameworks */, - 1CAEA24322D14FFE009CB9EB /* MiniOnePassword in Frameworks */, D5035BC16B0E9C1817003AF2 /* Pods_Awful.framework in Frameworks */, 1C47122A2664CB8000E5AA74 /* Smilies in Frameworks */, 1C6BDD24265CB31E005475CE /* Logger in Frameworks */, @@ -2147,7 +2145,6 @@ ); name = Awful; packageProductDependencies = ( - 1CAEA24222D14FFE009CB9EB /* MiniOnePassword */, 1C5C2B8C22D195BF00EA5A80 /* ImgurAnonymousAPI */, 1C453F272338457A007AC6CD /* Stencil */, 1CAF2371250C8CE400033F61 /* Nuke */, @@ -3474,10 +3471,6 @@ package = 1CCBDFF822CB02D500E1BE6A /* XCRemoteSwiftPackageReference "HTMLReader" */; productName = HTMLReader; }; - 1CAEA24222D14FFE009CB9EB /* MiniOnePassword */ = { - isa = XCSwiftPackageProductDependency; - productName = MiniOnePassword; - }; 1CAF2371250C8CE400033F61 /* Nuke */ = { isa = XCSwiftPackageProductDependency; package = 1CAF2370250C8CE400033F61 /* XCRemoteSwiftPackageReference "Nuke" */; From 73a62d98f8adefe14bb4abbc2d04d8032f298f17 Mon Sep 17 00:00:00 2001 From: dfsm Date: Sat, 7 Aug 2021 16:10:02 +1000 Subject: [PATCH 3/3] There are multiple causes for crashing while performing Full Reset (previously Log Out). This commit sorts one that was being caused by applicationWillResignActive and applicationDidBecomeActive and the SmilieKeyboardSetIsAwfulAppActive commands. Changed these to applicationWillEnterForeground and applicationDidEnterBackground, which seems to sort it. Hopefully this change is OK There is still one crash present due to coredata being deleted but still referenced in memory (I think?) --- App/Main/AppDelegate.swift | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/App/Main/AppDelegate.swift b/App/Main/AppDelegate.swift index 55feaf7e9..7b3e783f6 100644 --- a/App/Main/AppDelegate.swift +++ b/App/Main/AppDelegate.swift @@ -124,13 +124,13 @@ final class AppDelegate: UIResponder, UIApplicationDelegate { return true } - func applicationWillResignActive(_ application: UIApplication) { + func applicationDidEnterBackground(_ application: UIApplication) { SmilieKeyboardSetIsAwfulAppActive(false) updateShortcutItems() } - func applicationDidBecomeActive(_ application: UIApplication) { + func applicationWillEnterForeground(_ application: UIApplication) { SmilieKeyboardSetIsAwfulAppActive(true) // Screen brightness may have changed while the app wasn't paying attention. @@ -158,12 +158,19 @@ final class AppDelegate: UIResponder, UIApplicationDelegate { try! managedObjectContext.save() } + func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool { + AppDelegate.instance.application(app, open: url, + sourceApplication: options[UIApplication.OpenURLOptionsKey.sourceApplication] as? String, + annotation: options[UIApplication.OpenURLOptionsKey.annotation] as Any + ) + } + func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool { guard ForumsClient.shared.isLoggedIn, let route = try? AwfulRoute(url) - else { return false } - + else { return false } + open(route: route) return true }