-
Notifications
You must be signed in to change notification settings - Fork 22
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
A Sample App working with SwiftUI framework will help tremendously #47
Comments
Thanks for the request. I will update here once we add a sample with SwiftUi. |
+1 On this. I've just written an entire application in pure SwiftUI just went to add the Auth only to find that there is no examples for it at all. I probably should have looked at this first XD |
+1 to this. As a new dev learning SwiftUI I’m finding it difficult to implement a way to do this. |
+1 mil to this from me. waiting for almost a year now. |
+1 +1 to this. I tried using SwiftUI protocol UIViewControllerRepresentable to 'wrap' an UIViewController in a SwiftUI page view, but eventually got lost on how to pass it to MSALWebviewParameters. A SwiftUI example will definitely help a lot. |
+1 to this. |
+1 |
+1 to this too! I am currently working on a senior design capstone project, and this sample app or tutorial would be very beneficial! |
+1 to this.. |
I have experimented with this a little bit.
Let me know if you have found a different solution. P.S: the msContext is initialised in the
|
I was trying to solve a similar issue the other day, creating a SwiftUI based app from another MS Sample Project https://github.com/Azure-Samples/ms-identity-mobile-apple-swift-objc. I uploaded my SwiftUI sample here https://github.com/alschmut/MSALSwiftUI. From what I have tested until now, it seems to work fine with the MS Authenticator App. Feel free to have a look :) |
+1 for this request. I did see a post in StackOverflow with a similar request (which did get a response), but they all seem to be working around the problem. |
That's me! Here's the project. |
@arbyruns, have you looked at the @alschmut example which encapsulates all the authentication? I did this all in Android and am now trying to make it work in Swift but am a beginner. I see the call in @arbyruns: And in @alschmut's example: In @arbyruns it's called within a UIViewController class and his uses:
It seems like you should be able to abstract it from the UI, but need a callback/observable. Is there something Microsoft needs to do to enable this so we don't need an actual UIViewController in the call anywhere? |
Maybe help upvote this : https://feedback.azure.com/d365community/idea/ed66e827-c725-ec11-b6e6-000d3a4f0789 |
Since this request has been outstanding for so long, I'm concerned about the level of support moving forward. Maybe I should consider generic oAuth Swift options as B2C supports oAuth2, like https://github.com/OAuthSwift/OAuthSwift and https://github.com/p2/OAuth2 |
This is also discussed on the MSAL repository where a sample has been shared: AzureAD/microsoft-authentication-library-for-objc#1437 (comment) |
@antrix1989, how are we doing with this? |
Closed as duplicate. |
Status? Can't find duplicate nor any examples other than student pet projects |
@antrix1989 "Closed as duplicate." |
There was a code from @arbyruns which fitted the bill for me (source here), however it is compatible on older versions of iOS. Here is an updated version for iOS17: import SwiftUI
import UIKit
import Foundation
import MSAL
class MSALScreenViewModel: ObservableObject, MSALScreenViewModelProtocol{
var uiViewController: MSALScreenViewControllerProtocol? = nil
@Published var accountName: String = ""
@Published var scopes: [String] = []
func loadMSALScreen() {
print(#function)
uiViewController?.loadMSALScreen()
}
func getAccountName() -> String {
print(#function)
return accountName
}
}
struct MSALScreenView_UI: UIViewControllerRepresentable{
@ObservedObject var viewModel: MSALScreenViewModel
func makeUIViewController(context: Context) -> some MSALScreenViewController {
print(#function)
return MSALScreenViewController(viewModel: viewModel)
}
func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {
print(#function)
}
}
class MSALScreenViewController: UIViewController, MSALScreenViewControllerProtocol {
let kClientId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
let kRedirectUri = "msauth.YourProject://auth"
let kScopes: [String] = ["User.Read"]
let kAuthority = "https://login.microsoftonline.com/yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy"
var uiViewController: MSALScreenViewModelProtocol?
var viewModel: MSALScreenViewModelProtocol
init(viewModel: MSALScreenViewModelProtocol) {
print(#function)
self.viewModel = viewModel
super.init(nibName: nil, bundle: .main)
self.viewModel.uiViewController = self
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
print(#function)
viewModel.loadMSALScreen()
}
func loadMSALScreen() {
let msalModel = MSALScreenViewModel()
do {
let authority = try MSALAuthority(url: URL(string: kAuthority)!)
let pcaConfig = MSALPublicClientApplicationConfig(clientId: kClientId, redirectUri: kRedirectUri, authority: authority)
let application = try MSALPublicClientApplication(configuration: pcaConfig)
let webViewParameters = MSALWebviewParameters(authPresentationViewController: self)
let interactiveParameters = MSALInteractiveTokenParameters(scopes: kScopes, webviewParameters: webViewParameters)
application.acquireToken(with: interactiveParameters) { (result, error) in
guard let result = result else {
if let error = error {
print("Error: \(error.localizedDescription)")
} else {
print("Unknown error occurred")
}
return
}
if let account = result.account.username {
msalModel.accountName = account
msalModel.scopes = result.scopes
if let keyWindow = UIApplication.shared.currentUIWindow() {
keyWindow.rootViewController = UIHostingController(rootView: MicrosoftView())
}
}
}
} catch {
print("\(#function) logging error \(error)")
}
}
}
protocol MSALScreenViewModelProtocol{
var uiViewController: MSALScreenViewControllerProtocol? { get set }
func loadMSALScreen()
func getAccountName() -> String
}
protocol MSALScreenViewControllerProtocol: UIViewController{
var viewModel: MSALScreenViewModelProtocol { get set }
func loadMSALScreen()
}
struct MicrosoftView: View {
@StateObject var msalModel: MSALScreenViewModel = MSALScreenViewModel()
@State private var isLoggedIn: Bool = false
var body: some View {
NavigationStack {
VStack {
Spacer()
if isLoggedIn {
List {
NavigationLink(
destination: YourHomeView()
) {
HStack {
Text("Access Home")
.font(.subheadline)
.fontWeight(.bold)
}
}
}
} else {
Button("Login with Microsoft 365") {
msalModel.loadMSALScreen()
}
MSALScreenView_UI(viewModel: msalModel)
.frame(width: 250, height: 250, alignment: .center)
}
}
.onReceive(msalModel.$accountName) { accountName in
isLoggedIn = !accountName.isEmpty
}
}
}
}
public extension UIApplication {
func currentUIWindow() -> UIWindow? {
let connectedScenes = UIApplication.shared.connectedScenes
.filter { $0.activationState == .foregroundActive }
.compactMap { $0 as? UIWindowScene }
let window = connectedScenes.first?
.windows
.first { $0.isKeyWindow }
return window
}
}
#Preview {
MicrosoftView()
} |
@antrix1989 Can you please link the duplicate post? If there is no post, is there an update on a full SwiftUI implementation? |
No description provided.
The text was updated successfully, but these errors were encountered: