SwiftUI-MSALSample - Sample project to login with MSAL using SwiftUI

Overview

SwiftUI-MSALSample

I could not find a good walkthrough on how to implement MSAL with SwiftUI, everything is written for UIKit unfortunately and even then it wasn't clear IMO.

I started following the walkthrough Microsoft Authentication Library for iOS and macOS on github and then pieced together the rest using Stack Overflow.

There is still some work to be done. Please feel free to open a PR for any code improvements or adding features!

Getting Started the Short Version.

  1. Download the project.
  2. Follow the instructions listed on the AzureAD github to register your app within the Azure Portal.
  3. You will also want to follow the steps listed on adding MSAL to your project listed here.
  4. Updated clientID and redirectUri in MSALLogin.swift - MSALPublicClientApplicationConfig(clientId: clientID, redirectUri: redirectUri, authority: authority) with the information you got from when you registered your app in the azure portal.

Getting Started:

Installation

  1. I followed the instructions listed on the AzureAD github to register your app within the Azure Portal.
  2. You will also want to follow the steps listed on adding MSAL to your project listed here.

After step 2 is a bit where I got lost so I'm hoping this sample project will help.

Using This Sample Project

  1. Majority of the code is MSALLogin.swift and the big chuck of the code below is how you will login with MSAL.
  2. You'll want to replace clientID and redirectUri in MSALPublicClientApplicationConfig(clientId: clientID, redirectUri: redirectUri, authority: authority) with the information you got from when you registered your app in the azure portal. (Note: I have this info stored in a file that I did not upload.)
  3. Depending on your project you'll may also need to update your scopes in let interactiveParameters = MSALInteractiveTokenParameters(scopes: ["user.read"], webviewParameters: webViewParameters)
        do {
            let authority = try MSALB2CAuthority(url: URL(string: "https://login.microsoftonline.com/common")!)
            let pcaConfig = MSALPublicClientApplicationConfig(clientId: clientID, redirectUri: redirectUri, authority: authority)
            let application = try MSALPublicClientApplication(configuration: pcaConfig)
            let webViewParameters = MSALWebviewParameters(authPresentationViewController: self)
            let interactiveParameters = MSALInteractiveTokenParameters(scopes: ["user.read"], webviewParameters: webViewParameters)
            application.acquireToken(with: interactiveParameters) { (result, error) in

                guard let result = result else {
                    print("error \(error?.localizedDescription)")
                    return
                }
                if let account = result.account.username {
                    print("logging \(account)")
//                    accountName = account
                    msalModel.accountName = account
                    msalModel.scopes = result.scopes
                    print("logging \(result.account.description)")
                    UIApplication.shared.windows.first {
                        $0.isKeyWindow
                    }!.rootViewController = UIHostingController(rootView: ContentView())
                }
            }
        } catch {
            print("\(#function) logging error \(error)")
        }
  1. The rest of the code within MSALLogin.swift are methods and classes so UIKit and SwiftUI can work together.

Getting this to work with SwiftUI

  1. In ContentView.swift I declated a @StateObject linking back to MSALScreenViewModel() that I created in MSALLogin.swift.
  2. Within ContentView.swift I created a button that calls msalModel.loadMSALScreen() and then added the UIKit view MSALScreenView_UI(viewModel: msalModel). Just a heads up, but depending on how you implament this you will need to adjust the frame.

Challenges and Learning

  1. I'm not sure how I can dump result.account.username into the @Published var to use in other views. This will be beneficial for tokens to make other calls within MSFT products.
  2. I have not explored adding a sign out option.
  3. I'm unsure of how long the token would be for without having a silent refresh implemented.
  4. The biggest thing I learned is that Microsoft is not quite ready for SwiftUI and their documentation is lacking IMO for developers at least compared to Google Firebase. I do hope this changes in time.

Pictures of Repro

Video of Repro

Simulator.Screen.Recording.-.iPhone.13.-.2022-01-10.at.21.36.37.gifv.mp4
You might also like...
This is a mastodon sample SwiftUI app implemented with the architecture of state management with normalized cache.
This is a mastodon sample SwiftUI app implemented with the architecture of state management with normalized cache.

MastodonNormalizedCacheSample This is a mastodon sample SwiftUI app. This app is implemented with the architecture of state management with Normalized

Don't start from scratch, start from Here! This is a starter project for iOS projects. It contains all the basic configurations and common libraries for your project.

Starter-iOS Don't start from scratch, start from Here! This is a starter project for iOS projects. It contains all the basic configurations and common

NewsAPI-Project - News API Project For iOS
NewsAPI-Project - News API Project For iOS

NewsAPI-Project Es necesario descargar y realizar un pod install para ejecutar e

Tutorial GraphQL + Node Express + MySQL, and sample for Android / iOS client

GraphQL-tutorial Tutorial for GraphQL + Node Express + MySQL, and sample for Android / iOS client Blog NeoRoman's GraphQL-tutorial (Korean) Materials

Ios-exercise - In this exercise applicant should implement a new feature into an existing sample app

Cooking app In this exercise applicant should implement a new feature into an ex

This is an example project of SwiftUI and Combine using GitHub API.
This is an example project of SwiftUI and Combine using GitHub API.

SwiftUI-Combine-Example This is an example project of SwiftUI and Combine using GitHub GET /search/users API. 📋 Requirements Swift5.1 Beta Xcode11.0

Completed Project for Authentication in SwiftUI using Firebase Auth SDK & Sign in with Apple
Completed Project for Authentication in SwiftUI using Firebase Auth SDK & Sign in with Apple

Completed Project for Authentication in SwiftUI using Firebase Auth SDK & Sign in with Apple Follow the tutorial at alfianlosari.com Features Uses Fir

An iOS template project using SwiftUI, Combine and MVVM-C software architecture
An iOS template project using SwiftUI, Combine and MVVM-C software architecture

SwiftUI-MVVM-C A template project that uses SwiftUI for UI, Combine for event handling, MVVM-C for software architecture. I have done some small proje

This is an example project of SwiftUI and Combine using GitHub API.
This is an example project of SwiftUI and Combine using GitHub API.

SwiftUI-Combine-Example This is an example project of SwiftUI and Combine using GitHub GET /search/users API. 📋 Requirements Swift5.1 Beta Xcode11.0

Comments
  • error Optional(

    error Optional("The operation couldn’t be completed. (MSALErrorDomain error -50000.)")

    I seem to be making some progress but am now stuck on this error:

    error Optional("The operation couldn’t be completed. (MSALErrorDomain error -50000.)")

    I changed only:

    • clientID
    • redirectUri
    • scopes

    I used your Info.plist. I did not change the:

    • MSALB2CAuthority url, but did try with the Application ID URI from Azure
    opened by ljunquera 5
  • This may be a question but why is viewModel.loadMSALScreen() in viewDidLoad()

    This may be a question but why is viewModel.loadMSALScreen() in viewDidLoad()

    I kept on getting errors in the log and I realized the MSALScreenViewController called viewDidLoad() when starting and after I clicked the button. So loadMSALScreen() was called 3 times. Is that on purpose?

    opened by ljunquera 0
  • error Optional(

    error Optional("The operation couldn’t be completed. (MSALErrorDomain error -50000.)")

    Here is the log information

    makeUIViewController(context:)
    init(viewModel:)
    viewDidLoad()
    loadMSALScreen()
    error Optional("The operation couldn’t be completed. (MSALErrorDomain error -50000.)")
    updateUIViewController(_:context:)
    

    Here is what I did to set up the project after cloning it locally:

    • Deleted file: SwiftUI-MSALSample/SwiftUIMSAL/sekrets.swift
    • Hard coded CFBundleURLSchemes in the Info.plist: msauth.[bundle id]
    • Changed scopes: scopes: ["App.Standard"]
    • Created variable: var clientID : String = "[client id guid]"
    • Created variable: var redirectUri : String = "msauth.[bundle id]://auth"

    When I press the Login with MSAL button I get:

    loadMSALScreen()
    2022-01-19 18:07:40.657184-0500 SwiftUIMSAL[77698:2420183] [boringssl] boringssl_metrics_log_metric_block_invoke(151) Failed to log metrics
    error Optional("The operation couldn’t be completed. (MSALErrorDomain error -50000.)")
    2022-01-19 18:08:14.959067-0500 SwiftUIMSAL[77698:2419952] [BackgroundTask] Background Task 1 ("Interactive login"), was created over 30 seconds ago. In applications running in the background, this creates a risk of termination. Remember to call UIApplication.endBackgroundTask(_:) for your task in a timely manner to avoid this.
    
    opened by ljunquera 4
Owner
Rob Evans
Rob Evans
Sample iOS project built by SwiftUI + Flux and Combine framework using GitHub API

SwiftUI-Flux Flux enables us to have unidirectional data flow and make it testable. It's used to be implemented using RxSwift or ReactiveSwift in the

Yusuke Kita 87 Nov 25, 2022
Sample iOS project built by SwiftUI + MVVM and Combine framework using GitHub API

SwiftUI-MVVM One of the biggest idea for having MVVM is that most of data flow can be testable. Data binding in view layer by SwiftUI is awesome. Howe

Yusuke Kita 592 Jan 2, 2023
Swift Starter Kit with Firebase & Facebook Login Onboarding

iOS Swift Starter Kit ?? ?? ?? ?? Boilerplate Onboarding App in Swift with Firebase Integration, Facebook Login and Push Notifications. Save days of a

Instamobile 105 Nov 7, 2022
MVP-Clean sample iOS Swift project

RestaurantsApp MVP-Clean sample iOS Swift project The purpose of this document is to explain the architecture of application. This application shows r

Atul Ghorpade 2 May 1, 2022
A sample project how to use YOLOv5 in iOS

CoreML-YOLOv5 A sample project how to use YOLOv5 in iOS. You can run model on yo

MLBoy 32 Dec 19, 2022
SwiftUI sample app using Clean Architecture. Examples of working with CoreData persistence, networking, dependency injection, unit testing, and more.

Articles related to this project Clean Architecture for SwiftUI Programmatic navigation in SwiftUI project Separation of Concerns in Software Design C

Alexey Naumov 4k Jan 8, 2023
A sample SwiftUI weather app using Lasso.

Lasso+SwiftUI Example Weather App Overview This is a sample iOS app that demonstrates using Lasso and SwiftUI together. Feature Overview Home Screen D

WW Tech 2 Mar 19, 2022
WeatherSampleApp - Weather Sample app with SwiftUI consuming data from OpenWeather and using CoreLocation

WeatherSampleApp Weather application using SwiftUI Uses data provided by https:/

Juan Carlos Pazos 3 Jan 14, 2022
This is a sample app to create a photo selection classifier using CreateML on an iOS Device.

PhotoSelectionClassifier This is a sample app to create a photo selection classifier using CreateML on an iOS Device. Demo In the demo video below, we

null 15 Nov 18, 2022
SwiftUI sample code for Apple's WWDC18 talk "Designing Fluid Interfaces".

Fluid Interfaces SwiftUI SwiftUI sample code for Apple's WWDC18 talk "Designing Fluid Interfaces". What is Fluid Interfaces? Fluid Interfaces is a new

 Frad LEE 32 Oct 7, 2022