diff --git a/Mac/Resources/Info.plist b/Mac/Resources/Info.plist
index 579e08015..c6dc652a0 100644
--- a/Mac/Resources/Info.plist
+++ b/Mac/Resources/Info.plist
@@ -17,7 +17,7 @@
CFBundlePackageType
APPL
CFBundleShortVersionString
- 5.0a3
+ 5.0a4
CFBundleURLTypes
diff --git a/NetNewsWire.xcodeproj/project.pbxproj b/NetNewsWire.xcodeproj/project.pbxproj
index 275f9fb09..414f74d58 100644
--- a/NetNewsWire.xcodeproj/project.pbxproj
+++ b/NetNewsWire.xcodeproj/project.pbxproj
@@ -49,6 +49,8 @@
5183CCE9226F68D90010922C /* AccountRefreshTimer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5183CCE7226F68D90010922C /* AccountRefreshTimer.swift */; };
5183CCED22711DCE0010922C /* Settings.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5183CCEC22711DCE0010922C /* Settings.storyboard */; };
5183CCEF227125970010922C /* SettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5183CCEE227125970010922C /* SettingsViewController.swift */; };
+ 5194B5EE22B6965300144881 /* SettingsSubscriptionsImportDocumentPickerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5194B5ED22B6965300144881 /* SettingsSubscriptionsImportDocumentPickerView.swift */; };
+ 5194B5F222B69FCC00144881 /* SettingsSubscriptionsExportDocumentPickerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5194B5F122B69FCC00144881 /* SettingsSubscriptionsExportDocumentPickerView.swift */; };
519B8D332143397200FA689C /* SharingServiceDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 519B8D322143397200FA689C /* SharingServiceDelegate.swift */; };
51C451A9226377C200C03939 /* ArticlesDatabase.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8407167F2262A61100344432 /* ArticlesDatabase.framework */; };
51C451AA226377C200C03939 /* ArticlesDatabase.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8407167F2262A61100344432 /* ArticlesDatabase.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
@@ -320,6 +322,7 @@
D5F4EDB5200744A700B9E363 /* ScriptingObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5F4EDB4200744A700B9E363 /* ScriptingObject.swift */; };
D5F4EDB720074D6500B9E363 /* Feed+Scriptability.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5F4EDB620074D6500B9E363 /* Feed+Scriptability.swift */; };
D5F4EDB920074D7C00B9E363 /* Folder+Scriptability.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5F4EDB820074D7C00B9E363 /* Folder+Scriptability.swift */; };
+ DF999FF722B5AEFA0064B687 /* SafariView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF999FF622B5AEFA0064B687 /* SafariView.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -695,6 +698,8 @@
5183CCE7226F68D90010922C /* AccountRefreshTimer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountRefreshTimer.swift; sourceTree = ""; };
5183CCEC22711DCE0010922C /* Settings.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Settings.storyboard; sourceTree = ""; };
5183CCEE227125970010922C /* SettingsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewController.swift; sourceTree = ""; };
+ 5194B5ED22B6965300144881 /* SettingsSubscriptionsImportDocumentPickerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsSubscriptionsImportDocumentPickerView.swift; sourceTree = ""; };
+ 5194B5F122B69FCC00144881 /* SettingsSubscriptionsExportDocumentPickerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsSubscriptionsExportDocumentPickerView.swift; sourceTree = ""; };
519B8D322143397200FA689C /* SharingServiceDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SharingServiceDelegate.swift; sourceTree = ""; };
51C4524E226506F400C03939 /* UIStoryboard-Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIStoryboard-Extensions.swift"; sourceTree = ""; };
51C45250226506F400C03939 /* String-Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "String-Extensions.swift"; sourceTree = ""; };
@@ -930,6 +935,7 @@
D5F4EDB4200744A700B9E363 /* ScriptingObject.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScriptingObject.swift; sourceTree = ""; };
D5F4EDB620074D6500B9E363 /* Feed+Scriptability.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Feed+Scriptability.swift"; sourceTree = ""; };
D5F4EDB820074D7C00B9E363 /* Folder+Scriptability.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Folder+Scriptability.swift"; sourceTree = ""; };
+ DF999FF622B5AEFA0064B687 /* SafariView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SafariView.swift; sourceTree = ""; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -1049,12 +1055,22 @@
51F772EC22B2789B0087D9D1 /* SettingsDetailAccountView.swift */,
510D707F22B02A5F004E8F65 /* SettingsFeedbinAccountView.swift */,
510D707D22B02A4B004E8F65 /* SettingsLocalAccountView.swift */,
+ 5194B5F122B69FCC00144881 /* SettingsSubscriptionsExportDocumentPickerView.swift */,
+ 5194B5ED22B6965300144881 /* SettingsSubscriptionsImportDocumentPickerView.swift */,
51F35D0822AFD4760003CE1B /* SettingsView.swift */,
51F35CFD22AFD0350003CE1B /* UIKit */,
);
path = Settings;
sourceTree = "";
};
+ 5194B5E222B693EC00144881 /* Wrappers */ = {
+ isa = PBXGroup;
+ children = (
+ DF999FF622B5AEFA0064B687 /* SafariView.swift */,
+ );
+ path = Wrappers;
+ sourceTree = "";
+ };
51C45245226506C800C03939 /* Extensions */ = {
isa = PBXGroup;
children = (
@@ -1696,6 +1712,7 @@
5183CCEB227117C70010922C /* Settings */,
5183CCDB226F1EEB0010922C /* Progress */,
51C45245226506C800C03939 /* Extensions */,
+ 5194B5E222B693EC00144881 /* Wrappers */,
84C9FC9A2262A1A900D921D6 /* Resources */,
);
path = iOS;
@@ -2372,10 +2389,13 @@
51C452762265091600C03939 /* MasterTimelineViewController.swift in Sources */,
5183CCE9226F68D90010922C /* AccountRefreshTimer.swift in Sources */,
51C452882265093600C03939 /* AddFeedViewController.swift in Sources */,
+ DF999FF722B5AEFA0064B687 /* SafariView.swift in Sources */,
51C4529B22650A1000C03939 /* FaviconDownloader.swift in Sources */,
5183CCE3226F314C0010922C /* ProgressTableViewController.swift in Sources */,
512E09012268907400BDCFDD /* MasterFeedTableViewSectionHeader.swift in Sources */,
+ 5194B5F222B69FCC00144881 /* SettingsSubscriptionsExportDocumentPickerView.swift in Sources */,
51C45268226508F600C03939 /* MasterFeedUnreadCountView.swift in Sources */,
+ 5194B5EE22B6965300144881 /* SettingsSubscriptionsImportDocumentPickerView.swift in Sources */,
5183CCD0226E1E880010922C /* NonIntrinsicLabel.swift in Sources */,
51C4529F22650A1900C03939 /* AuthorAvatarDownloader.swift in Sources */,
51E595AD228E1C2100FCC42B /* AddAccountViewController.swift in Sources */,
diff --git a/iOS/Settings/SettingsDetailAccountView.swift b/iOS/Settings/SettingsDetailAccountView.swift
index 75f4fe1fe..dab8f30ce 100644
--- a/iOS/Settings/SettingsDetailAccountView.swift
+++ b/iOS/Settings/SettingsDetailAccountView.swift
@@ -9,10 +9,12 @@
import SwiftUI
import Combine
import Account
+import RSWeb
struct SettingsDetailAccountView : View {
@ObjectBinding var viewModel: ViewModel
@State private var verifyDelete = false
+ @State private var showFeedbinCredentials = false
var body: some View {
List {
@@ -26,15 +28,19 @@ struct SettingsDetailAccountView : View {
Text("Active")
}
}
- Section {
- HStack {
- Spacer()
- Button(action: {
-
- }) {
- Text("Credentials")
+ if viewModel.isCreditialsAvailable {
+ Section {
+ HStack {
+ Spacer()
+ Button(action: {
+ self.showFeedbinCredentials = true
+ }) {
+ Text("Credentials")
+ }
+ .presentation(showFeedbinCredentials ? feedbinCredentialsModal : nil)
+ .onDisappear() { self.showFeedbinCredentials = false }
+ Spacer()
}
- Spacer()
}
}
if viewModel.isDeletable {
@@ -62,6 +68,11 @@ struct SettingsDetailAccountView : View {
}
+ var feedbinCredentialsModal: Modal {
+ let feedbinViewModel = SettingsFeedbinAccountView.ViewModel(account: viewModel.account)
+ return Modal(SettingsFeedbinAccountView(viewModel: feedbinViewModel))
+ }
+
class ViewModel: BindableObject {
let didChange = PassthroughSubject()
let account: Account
@@ -94,6 +105,10 @@ struct SettingsDetailAccountView : View {
}
}
+ var isCreditialsAvailable: Bool {
+ return account.type != .onMyMac
+ }
+
var isDeletable: Bool {
return AccountManager.shared.defaultAccount != account
}
diff --git a/iOS/Settings/SettingsFeedbinAccountView.swift b/iOS/Settings/SettingsFeedbinAccountView.swift
index 50d425bc7..c867c94d2 100644
--- a/iOS/Settings/SettingsFeedbinAccountView.swift
+++ b/iOS/Settings/SettingsFeedbinAccountView.swift
@@ -16,8 +16,7 @@ struct SettingsFeedbinAccountView : View {
@ObjectBinding var viewModel: ViewModel
@State var busy: Bool = false
@State var error: Text = Text("")
- var account: Account? = nil
-
+
var body: some View {
NavigationView {
List {
@@ -25,15 +24,15 @@ struct SettingsFeedbinAccountView : View {
SettingsAccountLabelView(accountImage: "accountFeedbin", accountLabel: "Feedbin").padding()
) {
HStack {
- Spacer()
- TextField($viewModel.email, placeholder: Text("Email"))
- .textContentType(.username)
- Spacer()
+ Text("Email:")
+ Divider()
+ TextField($viewModel.email)
+ .textContentType(.username)
}
HStack {
- Spacer()
- SecureField($viewModel.password, placeholder: Text("Password"))
- Spacer()
+ Text("Password:")
+ Divider()
+ SecureField($viewModel.password)
}
}
Section(footer:
@@ -46,7 +45,11 @@ struct SettingsFeedbinAccountView : View {
HStack {
Spacer()
Button(action: { self.addAccount() }) {
- Text("Add Account")
+ if viewModel.isUpdate {
+ Text("Update Account")
+ } else {
+ Text("Add Account")
+ }
}
.disabled(!viewModel.isValid)
Spacer()
@@ -65,7 +68,8 @@ struct SettingsFeedbinAccountView : View {
private func addAccount() {
busy = true
-
+ error = Text("")
+
let emailAddress = viewModel.email.trimmingCharacters(in: .whitespaces)
let credentials = Credentials.basic(username: emailAddress, password: viewModel.password)
@@ -80,11 +84,11 @@ struct SettingsFeedbinAccountView : View {
var newAccount = false
let workAccount: Account
- if self.account == nil {
+ if self.viewModel.account == nil {
workAccount = AccountManager.shared.createAccount(type: .feedbin)
newAccount = true
} else {
- workAccount = self.account!
+ workAccount = self.viewModel.account!
}
do {
@@ -122,6 +126,18 @@ struct SettingsFeedbinAccountView : View {
class ViewModel: BindableObject {
let didChange = PassthroughSubject()
+ var account: Account? = nil
+
+ init() {
+ }
+
+ init(account: Account) {
+ self.account = account
+ if case .basic(let username, let password) = try? account.retrieveBasicCredentials() {
+ self.email = username
+ self.password = password
+ }
+ }
var email: String = "" {
didSet {
@@ -134,6 +150,10 @@ struct SettingsFeedbinAccountView : View {
}
}
+ var isUpdate: Bool {
+ return account != nil
+ }
+
var isValid: Bool {
return !email.isEmpty && !password.isEmpty
}
@@ -144,7 +164,7 @@ struct SettingsFeedbinAccountView : View {
#if DEBUG
struct SettingsFeedbinAccountView_Previews : PreviewProvider {
static var previews: some View {
- SettingsFeedbinAccountView(viewModel: SettingsFeedbinAccountView.ViewModel())
+ SettingsFeedbinAccountView(viewModel: SettingsFeedbinAccountView.ViewModel())
}
}
#endif
diff --git a/iOS/Settings/SettingsLocalAccountView.swift b/iOS/Settings/SettingsLocalAccountView.swift
index 40f671661..6247aea77 100644
--- a/iOS/Settings/SettingsLocalAccountView.swift
+++ b/iOS/Settings/SettingsLocalAccountView.swift
@@ -20,9 +20,9 @@ struct SettingsLocalAccountView : View {
SettingsAccountLabelView(accountImage: "accountLocal", accountLabel: Account.defaultLocalAccountName).padding()
) {
HStack {
- Spacer()
- TextField($name, placeholder: Text("Name (Optional)"))
- Spacer()
+ Text("Name")
+ Divider()
+ TextField($name, placeholder: Text("(Optional)"))
}
}
Section {
diff --git a/iOS/Settings/SettingsSubscriptionsExportDocumentPickerView.swift b/iOS/Settings/SettingsSubscriptionsExportDocumentPickerView.swift
new file mode 100644
index 000000000..a471c7d27
--- /dev/null
+++ b/iOS/Settings/SettingsSubscriptionsExportDocumentPickerView.swift
@@ -0,0 +1,31 @@
+//
+// SettingsSubscriptionsExportDocumentPickerView.swift
+// NetNewsWire-iOS
+//
+// Created by Maurice Parker on 6/16/19.
+// Copyright © 2019 Ranchero Software. All rights reserved.
+//
+
+import SwiftUI
+import Account
+
+struct SettingsSubscriptionsExportDocumentPickerView : UIViewControllerRepresentable {
+ var account: Account
+
+ func makeUIViewController(context: UIViewControllerRepresentableContext) -> UIDocumentPickerViewController {
+
+ let accountName = account.nameForDisplay.replacingOccurrences(of: " ", with: "").trimmingCharacters(in: .whitespaces)
+ let filename = "Subscriptions-\(accountName).opml"
+ let tempFile = FileManager.default.temporaryDirectory.appendingPathComponent(filename)
+
+ let opmlString = OPMLExporter.OPMLString(with: account, title: filename)
+ try? opmlString.write(to: tempFile, atomically: true, encoding: String.Encoding.utf8)
+
+ return UIDocumentPickerViewController(url: tempFile, in: .exportToService)
+ }
+
+ func updateUIViewController(_ uiViewController: UIDocumentPickerViewController, context: UIViewControllerRepresentableContext) {
+ //
+ }
+
+}
diff --git a/iOS/Settings/SettingsSubscriptionsImportDocumentPickerView.swift b/iOS/Settings/SettingsSubscriptionsImportDocumentPickerView.swift
new file mode 100644
index 000000000..4f4043a92
--- /dev/null
+++ b/iOS/Settings/SettingsSubscriptionsImportDocumentPickerView.swift
@@ -0,0 +1,43 @@
+//
+// SettingsSubscriptionsImportDocumentPickerView.swift
+// NetNewsWire-iOS
+//
+// Created by Maurice Parker on 6/16/19.
+// Copyright © 2019 Ranchero Software. All rights reserved.
+//
+
+import SwiftUI
+import Account
+
+struct SettingsSubscriptionsImportDocumentPickerView : UIViewControllerRepresentable {
+ var account: Account
+
+ func makeUIViewController(context: UIViewControllerRepresentableContext) -> UIDocumentPickerViewController {
+ let docPicker = UIDocumentPickerViewController(documentTypes: ["public.xml", "org.opml.opml"], in: .import)
+ docPicker.delegate = context.coordinator
+ return docPicker
+ }
+
+ func updateUIViewController(_ uiViewController: UIDocumentPickerViewController, context: UIViewControllerRepresentableContext) {
+ //
+ }
+
+ func makeCoordinator() -> Coordinator {
+ return Coordinator(self)
+ }
+
+ class Coordinator : NSObject, UIDocumentPickerDelegate {
+ var parent: SettingsSubscriptionsImportDocumentPickerView
+
+ init(_ view: SettingsSubscriptionsImportDocumentPickerView) {
+ self.parent = view
+ }
+
+ func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
+ for url in urls {
+ parent.account.importOPML(url) { result in}
+ }
+ }
+
+ }
+}
diff --git a/iOS/Settings/SettingsView.swift b/iOS/Settings/SettingsView.swift
index d0ddae653..1ca917abc 100644
--- a/iOS/Settings/SettingsView.swift
+++ b/iOS/Settings/SettingsView.swift
@@ -10,9 +10,15 @@ import SwiftUI
import Combine
import Account
+
+
struct SettingsView : View {
@ObjectBinding var viewModel: ViewModel
-
+ @State var subscriptionsImportAccounts: ActionSheet? = nil
+ @State var subscriptionsImportDocumentPicker: Modal? = nil
+ @State var subscriptionsExportAccounts: ActionSheet? = nil
+ @State var subscriptionsExportDocumentPicker: Modal? = nil
+
var body: some View {
NavigationView {
List {
@@ -31,30 +37,16 @@ struct SettingsView : View {
Section(header: Text("ABOUT")) {
Text("About NetNewsWire")
-
- Button(action: {
- UIApplication.shared.open(URL(string: "https://ranchero.com/netnewswire/")!, options: [:])
- }) {
- Text("Website")
- }
- Button(action: {
- UIApplication.shared.open(URL(string: "https://github.com/brentsimmons/NetNewsWire")!, options: [:])
- }) {
- Text("Github Repository")
- }
-
- Button(action: {
- UIApplication.shared.open(URL(string: "https://github.com/brentsimmons/NetNewsWire/issues")!, options: [:])
- }) {
- Text("Bug Tracker")
- }
-
- Button(action: {
- UIApplication.shared.open(URL(string: "https://github.com/brentsimmons/NetNewsWire/tree/master/Technotes")!, options: [:])
- }) {
- Text("Technotes")
- }
+ PresentationButton(Text("Website"), destination: SafariView(url: URL(string: "https://ranchero.com/netnewswire/")!))
+
+ PresentationButton(Text("Github Repository"), destination: SafariView(url: URL(string: "https://github.com/brentsimmons/NetNewsWire")!))
+
+ PresentationButton(Text("Bug Tracker"), destination: SafariView(url: URL(string: "https://github.com/brentsimmons/NetNewsWire/issues")!))
+
+ PresentationButton(Text("Technotes"), destination: SafariView(url: URL(string: "https://github.com/brentsimmons/NetNewsWire/tree/master/Technotes")!))
+
+ PresentationButton(Text("How to Support NetNewsWire"), destination: SafariView(url: URL(string: "https://github.com/brentsimmons/NetNewsWire/blob/master/Technotes/HowToSupportNetNewsWire.markdown")!))
Text("Add NetNewsWire News Feed")
@@ -76,10 +68,23 @@ struct SettingsView : View {
Text(interval.description()).tag(interval)
}
}
- Text("Import Subscriptions...")
- Text("Export Subscriptions...")
+ Button(action: {
+ self.subscriptionsImportAccounts = self.createSubscriptionsImportAccounts
+ }) {
+ Text("Import Subscriptions...")
+ }
+ .presentation(subscriptionsImportAccounts)
+ .presentation(subscriptionsImportDocumentPicker)
+ Button(action: {
+ self.subscriptionsExportAccounts = self.createSubscriptionsExportAccounts
+ }) {
+ Text("Export Subscriptions...")
+ }
+ .presentation(subscriptionsExportAccounts)
+ .presentation(subscriptionsExportDocumentPicker)
}
-
+ .foregroundColor(.primary)
+
}
.listStyle(.grouped)
.navigationBarTitle(Text("Settings"), displayMode: .inline)
@@ -87,6 +92,32 @@ struct SettingsView : View {
}
}
+ var createSubscriptionsImportAccounts: ActionSheet {
+ var buttons = [ActionSheet.Button]()
+ for account in viewModel.accounts {
+ let button = ActionSheet.Button.default(Text(verbatim: account.nameForDisplay)) {
+ self.subscriptionsImportAccounts = nil
+ self.subscriptionsImportDocumentPicker = Modal(SettingsSubscriptionsImportDocumentPickerView(account: account))
+ }
+ buttons.append(button)
+ }
+ buttons.append(.cancel { self.subscriptionsImportAccounts = nil })
+ return ActionSheet(title: Text("Import Subscriptions..."), message: Text("Select the account to import your OPML file into."), buttons: buttons)
+ }
+
+ var createSubscriptionsExportAccounts: ActionSheet {
+ var buttons = [ActionSheet.Button]()
+ for account in viewModel.accounts {
+ let button = ActionSheet.Button.default(Text(verbatim: account.nameForDisplay)) {
+ self.subscriptionsExportAccounts = nil
+ self.subscriptionsExportDocumentPicker = Modal(SettingsSubscriptionsExportDocumentPickerView(account: account))
+ }
+ buttons.append(button)
+ }
+ buttons.append(.cancel { self.subscriptionsExportAccounts = nil })
+ return ActionSheet(title: Text("Export Subscriptions..."), message: Text("Select the account to export out of."), buttons: buttons)
+ }
+
class ViewModel: BindableObject {
let didChange = PassthroughSubject()
diff --git a/iOS/Wrappers/SafariView.swift b/iOS/Wrappers/SafariView.swift
new file mode 100644
index 000000000..6b5d78334
--- /dev/null
+++ b/iOS/Wrappers/SafariView.swift
@@ -0,0 +1,52 @@
+//
+// SafariView.swift
+// NetNewsWire-iOS
+//
+// Created by Stuart Breckenridge on 16/6/19.
+// Copyright © 2019 Ranchero Software. All rights reserved.
+//
+
+import SwiftUI
+import SafariServices
+
+struct SafariView : UIViewControllerRepresentable {
+
+ let url: URL
+
+ func makeUIViewController(context: UIViewControllerRepresentableContext) -> SFSafariViewController {
+ let safari = SFSafariViewController(url: url)
+ safari.delegate = context.coordinator
+ return safari
+ }
+
+ func updateUIViewController(_ uiViewController: SFSafariViewController, context: UIViewControllerRepresentableContext) {
+ //
+ }
+
+ func makeCoordinator() -> Coordinator {
+ return Coordinator(self)
+ }
+
+ class Coordinator : NSObject, SFSafariViewControllerDelegate {
+ var parent: SafariView
+
+ init(_ safariView: SafariView) {
+ self.parent = safariView
+ }
+
+ // MARK: SFSafariViewControllerDelegate
+ func safariViewControllerDidFinish(_ controller: SFSafariViewController) {
+
+ }
+
+ func safariViewController(_ controller: SFSafariViewController, initialLoadDidRedirectTo URL: URL) {
+
+ }
+
+ func safariViewController(_ controller: SFSafariViewController, didCompleteInitialLoad didLoadSuccessfully: Bool) {
+
+ }
+ }
+}
+
+