From 649972f57f872b6ec6147ea63a7458438a32f295 Mon Sep 17 00:00:00 2001 From: Maurice Parker Date: Sat, 28 Mar 2020 16:51:41 -0500 Subject: [PATCH] Created the Developer build which has some functionality disabled for those without access to the API keys needed. --- Mac/AppDefaults.swift | 7 + Mac/MainWindow/MainWindowController.swift | 4 + .../Accounts/AccountsAddViewController.swift | 25 +- README.md | 31 ++- iOS/AppDefaults.swift | 7 + iOS/Article/ArticleViewController.swift | 2 +- iOS/Settings/AddAccountViewController.swift | 87 +++++- iOS/Settings/Settings.storyboard | 259 ++++-------------- 8 files changed, 175 insertions(+), 247 deletions(-) diff --git a/Mac/AppDefaults.swift b/Mac/AppDefaults.swift index a61ca84d0..89d42b928 100644 --- a/Mac/AppDefaults.swift +++ b/Mac/AppDefaults.swift @@ -48,6 +48,13 @@ struct AppDefaults { private static let smallestFontSizeRawValue = FontSize.small.rawValue private static let largestFontSizeRawValue = FontSize.veryLarge.rawValue + static let isDeveloperBuild: Bool = { + if let dev = Bundle.main.object(forInfoDictionaryKey: "DeveloperEntitlements") as? String, dev == "-dev" { + return true + } + return false + }() + static let isFirstRun: Bool = { if let _ = UserDefaults.standard.object(forKey: Key.firstRunDate) as? Date { return false diff --git a/Mac/MainWindow/MainWindowController.swift b/Mac/MainWindow/MainWindowController.swift index c4f5c2a44..8e24bf155 100644 --- a/Mac/MainWindow/MainWindowController.swift +++ b/Mac/MainWindow/MainWindowController.swift @@ -799,6 +799,10 @@ private extension MainWindowController { } func validateToggleArticleExtractor(_ item: NSValidatedUserInterfaceItem) -> Bool { + guard !AppDefaults.isDeveloperBuild else { + return false + } + guard let toolbarItem = item as? NSToolbarItem, let toolbarButton = toolbarItem.view as? ArticleExtractorButton else { if let menuItem = item as? NSMenuItem { menuItem.state = isShowingExtractedArticle ? .on : .off diff --git a/Mac/Preferences/Accounts/AccountsAddViewController.swift b/Mac/Preferences/Accounts/AccountsAddViewController.swift index 4923272be..a01adf796 100644 --- a/Mac/Preferences/Accounts/AccountsAddViewController.swift +++ b/Mac/Preferences/Accounts/AccountsAddViewController.swift @@ -34,7 +34,7 @@ class AccountsAddViewController: NSViewController { super.viewDidLoad() tableView.dataSource = self tableView.delegate = self - removeCloudKitIfNecessary() + restrictAccounts() } } @@ -104,7 +104,7 @@ extension AccountsAddViewController: NSTableViewDelegate { let accountsAddCloudKitWindowController = AccountsAddCloudKitWindowController() accountsAddCloudKitWindowController.runSheetOnWindow(self.view.window!) { response in if response == NSApplication.ModalResponse.OK { - self.removeCloudKitIfNecessary() + self.restrictAccounts() self.tableView.reloadData() } } @@ -161,21 +161,22 @@ extension AccountsAddViewController: OAuthAccountAuthorizationOperationDelegate private extension AccountsAddViewController { - func removeCloudKitIfNecessary() { - func removeCloudKit() { - if let cloudKitIndex = addableAccountTypes.firstIndex(of: .cloudKit) { - addableAccountTypes.remove(at: cloudKitIndex) + func restrictAccounts() { + func removeAccountType(_ accountType: AccountType) { + if let index = addableAccountTypes.firstIndex(of: accountType) { + addableAccountTypes.remove(at: index) } } - if AccountManager.shared.activeAccounts.firstIndex(where: { $0.type == .cloudKit }) != nil { - removeCloudKit() + if AppDefaults.isDeveloperBuild { + removeAccountType(.cloudKit) + removeAccountType(.feedly) + removeAccountType(.feedWrangler) return } - - // We don't want developers without entitlements to be trying to add the CloudKit account - if let dev = Bundle.main.object(forInfoDictionaryKey: "DeveloperEntitlements") as? String, dev == "-dev" { - removeCloudKit() + + if AccountManager.shared.activeAccounts.firstIndex(where: { $0.type == .cloudKit }) != nil { + removeAccountType(.cloudKit) } } diff --git a/README.md b/README.md index cc22b59bf..f53c59995 100644 --- a/README.md +++ b/README.md @@ -40,8 +40,9 @@ This allows for a pristine project with code signing set up with the appropriate developer ID and certificates, and for dev to be able to have local settings without needing to check in anything into source control. -As an example, make a directory SharedXcodeSettings next to where you have this repository. -An example of the structure is: +Make a directory SharedXcodeSettings next to where you have this repository. + +The directory structure is: ``` aDirectory/ @@ -50,6 +51,13 @@ aDirectory/ NetNewsWire NetNewsWire.xcworkspace ``` +Example: + +If your NetNewsWire Xcode project file is at: +`/Users/Shared/git/NetNewsWire/NetNewsWire.xcodeproj` + +Create your `DeveloperSettings.xcconfig` file at +`/Users/Shared/git/SharedXcodeSettings/DeveloperSettings.xcconfig` Then create a plain text file in it: `SharedXcodeSettings/DeveloperSettings.xcconfig` and give it the contents: @@ -63,16 +71,17 @@ DEVELOPER_ENTITLEMENTS = -dev PROVISIONING_PROFILE_SPECIFIER = ``` -You can use Keychain Acceass to [find your development team ID](/Technotes/FindingYourDevelopmentTeamID.md). +Set `DEVELOPMENT_TEAM` to your Apple supplied development team. You can use Keychain +Acceass to [find your development team ID](/Technotes/FindingYourDevelopmentTeamID.md). +Set `ORGANIZATION_IDENTIFIER` to a reversed domain name that you control or have made up. Note that `PROVISIONING_PROFILE_SPECIFIER` should not have a value associated with it. +You can now open the `NetNewsWire.xcworkspace` in Xcode. + Now you should be able to build without code signing errors and without modifying -the NetNewsWire Xcode project. +the NetNewsWire Xcode project. This is a special build of NetNewsWire with some +functionality disabled. This is because we have API keys that can't be stored in the +repository or shared between developers. Certain account types, like Feedly, aren't +enabled and the Reader View isn't enabled because of this. -Example: - -If your NetNewsWire Xcode project file is at: -`/Users/Shared/git/NetNewsWire/NetNewsWire.xcodeproj` - -Create your `DeveloperSettings.xcconfig` file at -`/Users/Shared/git/SharedXcodeSettings/DeveloperSettings.xcconfig` +If you have any problems, we will help you out in Slack (see above). diff --git a/iOS/AppDefaults.swift b/iOS/AppDefaults.swift index f790db2a6..986378b00 100644 --- a/iOS/AppDefaults.swift +++ b/iOS/AppDefaults.swift @@ -52,6 +52,13 @@ struct AppDefaults { static let addFolderAccountID = "addFolderAccountID" } + static let isDeveloperBuild: Bool = { + if let dev = Bundle.main.object(forInfoDictionaryKey: "DeveloperEntitlements") as? String, dev == "-dev" { + return true + } + return false + }() + static let isFirstRun: Bool = { if let _ = AppDefaults.shared.object(forKey: Key.firstRunDate) as? Date { return false diff --git a/iOS/Article/ArticleViewController.swift b/iOS/Article/ArticleViewController.swift index 3768d3441..d6227ccab 100644 --- a/iOS/Article/ArticleViewController.swift +++ b/iOS/Article/ArticleViewController.swift @@ -153,7 +153,7 @@ class ArticleViewController: UIViewController { starBarButtonItem.isEnabled = true let permalinkPresent = article.preferredLink != nil - articleExtractorButton.isEnabled = permalinkPresent + articleExtractorButton.isEnabled = permalinkPresent && !AppDefaults.isDeveloperBuild actionBarButtonItem.isEnabled = permalinkPresent if article.status.read { diff --git a/iOS/Settings/AddAccountViewController.swift b/iOS/Settings/AddAccountViewController.swift index 870b7e1f1..7b3b91318 100644 --- a/iOS/Settings/AddAccountViewController.swift +++ b/iOS/Settings/AddAccountViewController.swift @@ -16,47 +16,81 @@ protocol AddAccountDismissDelegate: UIViewController { class AddAccountViewController: UITableViewController, AddAccountDismissDelegate { - @IBOutlet private weak var localAccountImageView: UIImageView! - @IBOutlet private weak var localAccountNameLabel: UILabel! - + #if DEBUG + private var addableAccountTypes: [AccountType] = [.onMyMac, .feedbin, .feedly, .feedWrangler, .newsBlur] + #else + private var addableAccountTypes: [AccountType] = [.onMyMac, .feedbin, .feedly] + #endif + override func viewDidLoad() { super.viewDidLoad() - localAccountImageView.image = AppAssets.image(for: .onMyMac) - localAccountNameLabel.text = Account.defaultLocalAccountName + restrictAccounts() + } + + override func numberOfSections(in tableView: UITableView) -> Int { + 1 } - #if !DEBUG override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - return 3 + return addableAccountTypes.count + } + + override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { + return 52.0 + } + + override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = tableView.dequeueReusableCell(withIdentifier: "SettingsAccountTableViewCell", for: indexPath) as! SettingsAccountTableViewCell + + switch addableAccountTypes[indexPath.row] { + case .onMyMac: + cell.accountNameLabel?.text = Account.defaultLocalAccountName + cell.accountImage?.image = AppAssets.image(for: .onMyMac) + case .feedbin: + cell.accountNameLabel?.text = NSLocalizedString("Feedbin", comment: "Feedbin") + cell.accountImage?.image = AppAssets.accountFeedbinImage + case .feedWrangler: + cell.accountNameLabel?.text = NSLocalizedString("Feed Wrangler", comment: "Feed Wrangler") + cell.accountImage?.image = AppAssets.accountFeedWranglerImage + case .feedly: + cell.accountNameLabel?.text = NSLocalizedString("Feedly", comment: "Feedly") + cell.accountImage?.image = AppAssets.accountFeedlyImage + case .newsBlur: + cell.accountNameLabel?.text = NSLocalizedString("NewsBlur", comment: "NewsBlur") + cell.accountImage?.image = AppAssets.accountNewsBlurImage + default: + break + } + + return cell } - #endif override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - switch indexPath.row { - case 0: + switch addableAccountTypes[indexPath.row] { + case .onMyMac: let navController = UIStoryboard.account.instantiateViewController(withIdentifier: "AddLocalAccountNavigationViewController") as! UINavigationController navController.modalPresentationStyle = .currentContext let addViewController = navController.topViewController as! LocalAccountViewController addViewController.delegate = self present(navController, animated: true) - case 1: + case .feedbin: let navController = UIStoryboard.account.instantiateViewController(withIdentifier: "FeedbinAccountNavigationViewController") as! UINavigationController navController.modalPresentationStyle = .currentContext let addViewController = navController.topViewController as! FeedbinAccountViewController addViewController.delegate = self present(navController, animated: true) - case 2: + case .feedly: let addAccount = OAuthAccountAuthorizationOperation(accountType: .feedly) addAccount.delegate = self addAccount.presentationAnchor = self.view.window! MainThreadOperationQueue.shared.add(addAccount) - case 3: + case .feedWrangler: let navController = UIStoryboard.account.instantiateViewController(withIdentifier: "FeedWranglerAccountNavigationViewController") as! UINavigationController navController.modalPresentationStyle = .currentContext let addViewController = navController.topViewController as! FeedWranglerAccountViewController addViewController.delegate = self present(navController, animated: true) - case 4: + case .newsBlur: let navController = UIStoryboard.account.instantiateViewController(withIdentifier: "NewsBlurAccountNavigationViewController") as! UINavigationController navController.modalPresentationStyle = .currentContext let addViewController = navController.topViewController as! NewsBlurAccountViewController @@ -97,3 +131,28 @@ extension AddAccountViewController: OAuthAccountAuthorizationOperationDelegate { presentError(error) } } + +// MARK: Private + +private extension AddAccountViewController { + + func restrictAccounts() { + func removeAccountType(_ accountType: AccountType) { + if let index = addableAccountTypes.firstIndex(of: accountType) { + addableAccountTypes.remove(at: index) + } + } + + if AppDefaults.isDeveloperBuild { + removeAccountType(.cloudKit) + removeAccountType(.feedly) + removeAccountType(.feedWrangler) + return + } + + if AccountManager.shared.activeAccounts.firstIndex(where: { $0.type == .cloudKit }) != nil { + removeAccountType(.cloudKit) + } + } + +} diff --git a/iOS/Settings/Settings.storyboard b/iOS/Settings/Settings.storyboard index 2b2a986bc..7d7c0f0f6 100644 --- a/iOS/Settings/Settings.storyboard +++ b/iOS/Settings/Settings.storyboard @@ -1,8 +1,8 @@ - + - + @@ -320,7 +320,7 @@ - + @@ -356,7 +356,7 @@ - + @@ -373,7 +373,7 @@ - + @@ -390,7 +390,7 @@ - + @@ -407,7 +407,7 @@ - + @@ -424,7 +424,7 @@ - + @@ -441,7 +441,7 @@ - + @@ -458,7 +458,7 @@ - + @@ -475,7 +475,7 @@ - + @@ -523,209 +523,54 @@ - + - - - - - - - - - + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - - @@ -1083,11 +928,7 @@ - - - -