Closed amalashin closed 4 years ago
Hi @amalashin - subscription
is not being retained so the network request gets canceled before your closures are called. Try:
var subscriptions = Set<AnyCancellable>()
//... other stuff in SceneDelegate
func sceneDidBecomeActive(_ scene: UIScene) {
// Set up Salesforce with Connected App info
sfdc.identity().sink(receiveCompletion: { (completion) in
print(completion)
}) { identity in
print(identity)
}.store(in: &subscriptions)
}
🤦🏻♂️ It seems like I need to learn a little bit more about Combine. Thank you for clarification.
Am I right that the authentication question will be automatically opened with any request in case of the expired token?
It looks like I finally got it! At least, it works for me (and may be will be useful for someone) :) Could you please check.
UserSettings.swift
final class UserSettings: ObservableObject {
private var sfdc: Salesforce
private var disposables = Set<AnyCancellable>()
@Published var identity: Identity? = nil
init() {
let consumerKey = "3MVG9wEVwV..................HkrL82X"
let callbackURL = URL(string: "sfdc://authorization/done")!
let connectedApp = ConnectedApp(consumerKey: consumerKey, callbackURL: callbackURL)
self.sfdc = Salesforce(connectedApp: connectedApp)
self.sfdc.identity()
.receive(on: RunLoop.main)
.eraseToAnyPublisher()
.sink(
receiveCompletion: { [weak self] value in
guard let self = self else { return }
switch value {
case let .failure(error):
print("Error: \(error)")
self.identity = nil
break
case .finished:
print("Finished receiving Identity!")
break
}
},
receiveValue: {
self.identity = $0
print("Identity user: \($0.displayName)")
}
).store(in: &disposables)
}
}
SceneDelegate.swift
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
let mainView = MainView().environmentObject(UserSettings())
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
window.rootViewController = UIHostingController(rootView: mainView)
self.window = window
window.makeKeyAndVisible()
}
}
}
MainView.swift
struct MainView: View {
@EnvironmentObject var userSettings: UserSettings
var body: some View {
if userSettings.identity != nil {
return AnyView(UserView())
} else {
return AnyView(LoadingView())
}
}
}
struct UserView: View {
@EnvironmentObject var userSettings: UserSettings
var body: some View {
VStack {
VStack {
CircleImage(image: Image("none"))
Text(userSettings.identity != nil ? userSettings.identity!.displayName : "none")
}
}
}
}
struct LoadingView: View {
var body: some View {
Text("Loading...")
}
}
Hi @amalashin in answer to your question on authentication:
Yes, correct - Swiftly Salesforce will automatically initiate re-authentication if the stored token has expired.
You could override this default behavior if the user might be confused by the appearance of the Salesforce login form -- see RequestConfig and set authenticateIfRequired
to false
.
@amalashin I will close this issue for now - if you have more questions, please re-open or create another.
Hello! It seems like SwiftySalesforce is an awesome package but I totally cannot set it up. I tried almost everything and spend around two days 😱 with trying to bring things to work. Explored README as well as #114 and #115 and totally misunderstood what I'm doing wrong. So, do you have a working example?...
For now I have in SceneDelegate.swift:
When I start an app, I got a message to allow to authorize. After authorization I got nothing.... What I am doing wrong? 😒