我是一个来自.NET世界的xCode / Swift新手。我已经按照iOS应用指南(https://docs.microsoft.com/en-us/azure/active-directory/develop/guidedsetups/active-directory-ios)中调用Microsoft Graph API中列出的步骤进行了操作,但是出现了构建错误: Swift编译错误:没有这样的模块'MSAL'在ViewController.swift中。重新检查了一切,但仍无法解决。
这是ViewController类:
//
// ViewController.swift
// ATCO MSAL Login Demo
//
// Created by user128987 on 8/23/17.
// Copyright © 2017 atco.com. All rights reserved.
//
import UIKit
import MSAL
class ViewController: UIViewController, UITextFieldDelegate, URLSessionDelegate {
let kClientID = "91600c46-........"
let kAuthority = "https://login.microsoftonline.com/common/v2.0"
let kGraphURI = "https://graph.microsoft.com/v1.0/me/"
let kScopes: [String] = ["https://graph.microsoft.com/user.read"]
var accessToken = string()
var applicationContext = MSALPublicClientApplication.init()
@IBOutlet weak var loggingText: UITextView!
@IBOutlet weak var signoutButton: UIButton!
// This button will invoke the call to the Microsoft Graph API. It uses the
// built in Swift libraries to create a connection.
@IBAction func callGraphButton(_ sender: UIButton) {
do {
// We check to see if we have a current logged in user. If we don't, then we need to sign someone in.
// We throw and interactionRequired so that we trigger the interactive sign in.
if try self.applicationContext.users().isEmpty {
throw NSError.init(domain: "MSALErrorDomain", code: MSALErrorCode.interactionRequired.rawValue, userInfo: nil)
} else {
// Acquire a token for an existing user silently
try self.applicationContext.acquireTokenSilent(forScopes: self.kScopes, user: applicationContext.users().first) { (result, error) in
if error == nil {
self.accessToken = (result?.accessToken)!
self.loggingText.text = "Refreshing token sliently)"
self.loggingText.text = "Refreshed Access token is \(self.accessToken)"
self.singoutButton.isEnabled = true;
self.getContentWithToken()
} else {
self.loggingText.text = "Could not acquire token silently: \(error ?? "No error information" as! Error)"
}
}
}
} catch let error as NSError {
// interactionRequired means we need to ask the user to sign-in. This usually happens
// when the user's Refresh Token is expired or if the user has changed their password
// among other possibilities
if error.code == MSALErrorCode.iteractionRequire.rawValue {
self.applicationContext.acquireToken(forScopes: self.kScopes) { (result, error) in
if error == nil {
sel.accessToken = (result?.accessToken)!
self.loggingText.text = "Access token is \(self.accessToken)"
self.signoutButton.isEnabled = true;
self.getConetnWithToken()
} else {
self.loggingtext.text = "Could not acquire token: \(error ?? "No error information" as! Error)"
}
}
}
} catch {
// This is the catch all error.
self.loggingText.text = "Unable to acquire token. Got error: \(error)"
}
}
override func viewDidLoad() {
super.viewDidLoad()
do {
// Inititalize a MSALPublicClinetApplication with a given clientID and authority
self.applicationContext = try MSALPublicClinetApplication.init(clientId: kClientID, authority: kAuthority)
} catch {
self.loggingText.text = "Unable to create Appliocation context. Error \(error)"
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func viewWillAppear(_ animated: Bool) {
if self.accessToken.isEmpty {
singoutButton.isEnabled = false;
}
}
func getContentWithToken() {
let sessionConfig = URLSessionConfiguration.default
// Specify the Graph API endpoint
let url = URL(string: kGraphURI)
var request = URLRequest(url: url!)
// Set the Authorization header for the request. We use Bearer tokens, so we specify Bearer + the token we got from the result
request.setValue("Bearer \(self.accessToken)", forHTTPHeaderField: "Authorization")
let urlSession = URLSession(configuration: sessionConfig, delegate: self, delegateQueue: OperationQueue.main)
urlSession.dataTask(with: request) { data, response, error in
let result = try? JSONSerialization.jsonObject(with: data!, options: [])
if result != nil {
self.loggingText.text = result.debugDescription
}
}.resume()
}
@IBAction func signoutButton(_ sender: UIButton) {
do {
// Removes all tokens from the cache for this application for the provided user
// first parameter: The user to remove from the cache
try self.applicationContext.remove(self.applicationContext.users().first)
self.signoutButton.isEnabled = false;
} catch let error {
self.loggingText.text = "Received error signing user out: \(error)"
}
}
}
编辑1: 其他背景 - 我在MacInCloud上运行(如果它有所不同)。
我终于能够通过更改Build Phases>下的Input Files来在模拟器中构建和运行代码。从 $(SRCROOT)/Carthage/Build/iOS/MSAL.framework 运行脚本到 /Users/user128987/Carthage/Build/iOS/MSAL.Framework 。
所以我的问题是,脚本 / usr / local / bin / carthage copy-frameworks 如何知道将框架复制到$(SRCROOT)/Carthage/Build/iOS/MSAL.Framework **为什么它不适合我。
上述更改允许我在iOS模拟器中构建和运行项目,但在将活动方案更改为通用iOS设备之后,我不会将其归档。为什么呢?