Giter VIP home page Giter VIP logo

ios-swift-connect-sample's Introduction

Office 365 Connect Sample for iOS (Swift) Using the Microsoft Graph SDK

Microsoft Graph is a unified endpoint for accessing data, relationships and insights that come from the Microsoft Cloud. This sample shows how to connect and authenticate to it, and then call mail and user APIs through the Microsoft Graph SDK for iOS.

Note: Try out the Microsoft Graph App Registration Portal page which simplifies registration so you can get this sample running faster.

Prerequisites

  • Xcode from Apple -This sample is currently tested and supported on version 8.2.1 of Xcode.

  • Installation of CocoaPods as a dependency manager.

  • A Microsoft work or personal email account such as Office 365, or outlook.com, hotmail.com, etc. You can sign up for an Office 365 Developer subscription that includes the resources that you need to start building Office 365 apps.

    Note: If you already have a subscription, the previous link sends you to a page with the message Sorry, you can’t add that to your current account. In that case, use an account from your current Office 365 subscription.

  • A client id from the registered app at Microsoft Graph App Registration Portal

  • To make requests, an MSAuthenticationProvider must be provided which is capable of authenticating HTTPS requests with an appropriate OAuth 2.0 bearer token. We will be using msgraph-sdk-ios-nxoauth2-adapter for a sample implementation of MSAuthenticationProvider that can be used to jump-start your project. See the below section Code of Interest for more information.

Note: The sample was tested on Xcode 8.2.1. This sample supports Xcode 8 and iOS10, which uses the Swift 3.0 framework.

Running this sample in Xcode

  1. Clone this repository

  2. Use CocoaPods to import the Microsoft Graph SDK and authentication dependencies:

     pod 'MSGraphSDK'
     pod 'MSGraphSDK-NXOAuth2Adapter'
    

This sample app already contains a podfile that will get the pods into the project. Simply navigate to the project From Terminal and run:

    pod install

For more information, see Using CocoaPods in Additional Resources

  1. Open Graph-iOS-Swift-Connect.xcworkspace

  2. Open AutheticationConstants.swift under Application folder. You'll see that the clientId from the registration process can be added to this file.

         static let clientId = "ENTER_YOUR_CLIENT_ID"

    Note: You'll notice that the following permission scopes have been configured for this project: "https://graph.microsoft.com/Mail.Send", "https://graph.microsoft.com/User.Read", "offline_access". The service calls used in this project, sending a mail to your mail account and retriving some profile information (Display Name, Email Address) require these permissions for the app to run properly.

  3. Run the sample. You'll be asked to connect/authenticate to a work or personal mail account, and then you can send a mail to that account, or to another selected email account.

Code of Interest

All authentication code can be viewed in the Authentication.swift file. We use a sample implementation of MSAuthenticationProvider extended from NXOAuth2Client to provide login support for registered native apps, automatic refreshing of access tokens, and logout functionality:

Authenticate the user

        // Set client ID
        NXOAuth2AuthenticationProvider.setClientId(clientId, scopes: scopes)
        
        // Try silent log in. This will attempt to sign in if there is a previous successful
        // sign in user information.
        if NXOAuth2AuthenticationProvider.sharedAuth().loginSilent() == true {
            completion(nil)
        }
        // Otherwise, present log in controller.
        else {
            NXOAuth2AuthenticationProvider.sharedAuth()
                .login(with: nil) { (error: Error?) in
                    
                    if let nserror = error {
                        completion(MSGraphError.nsErrorType(error: nserror as NSError))
                    }
                    else {
                        completion(nil)
                    }
            }
        }
    ...
    
    func disconnect() {
        NXOAuth2AuthenticationProvider.sharedAuth().logout()
    }

Once the authentication provider is set, we can create and initialize a client object (MSGraphClient) that will be used to make calls against the Microsoft Graph service endpoint (mail and users). In SendViewcontroller.swift we can assemble a mail request and send it using the following code:

Get user profile picture

        self.graphClient.me().photoValue().download {
            (url: URL?, response: URLResponse?, error: Error?) in
            
                guard let picUrl = url else {
                    return
                }
            
                let picData = NSData(contentsOf: picUrl)
                let picImage = UIImage(data: picData! as Data)
            
                if let validPic = picImage {
                    completion(.success(validPic))
                }
            }

Upload the picture to OneDrive

        let data = UIImageJPEGRepresentation(unwrappedImage, 1.0)
        self.graphClient
            .me()
            .drive()
            .root()
            .children()
            .driveItem("me.png")
            .contentRequest()
            .upload(from: data, completion: {
                (driveItem: MSGraphDriveItem?, error: Error?) in
                if let nsError = error {
                    return
                } else {
                    webUrl = (driveItem?.webUrl)!
                }
            })

Attach the picture to a new email message

            let fileAttachment = MSGraphFileAttachment()
            let data = UIImageJPEGRepresentation(unwrappedImage, 1.0)
            fileAttachment.contentType = "image/png"
            fileAttachment.oDataType = "#microsoft.graph.fileAttachment"
            fileAttachment.contentBytes = data?.base64EncodedString()
            fileAttachment.name = "me.png"
            message.attachments.append(fileAttachment)

Send the message

    let requestBuilder = graphClient.me().sendMail(with: message, saveToSentItems: false)
    let mailRequest = requestBuilder?.request()
            
        mailRequest?.execute(completion: {
            (response: [AnyHashable: Any]?, error: Error?) in
            if let nsError = error {
                print(NSLocalizedString("ERROR", comment: ""), nsError.localizedDescription)
                DispatchQueue.main.async(execute: {
                    self.statusTextView.text = NSLocalizedString("SEND_FAILURE", comment: "")
                })
                    
            }

...            

For more information, including code to call into other services like OneDrive, see the Microsoft Graph SDK for iOS

Questions and comments

We'd love to get your feedback about the Office 365 iOS Microsoft Graph Connect project. You can send your questions and suggestions to us in the Issues section of this repository.

Questions about Office 365 development in general should be posted to Stack Overflow. Make sure that your questions or comments are tagged with [Office365] and [MicrosoftGraph].

Contributing

You will need to sign a Contributor License Agreement before submitting your pull request. To complete the Contributor License Agreement (CLA), you will need to submit a request via the form and then electronically sign the CLA when you receive the email containing the link to the document.

This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact [email protected] with any additional questions or comments.

Additional resources

Copyright

Copyright (c) 2016 Microsoft. All rights reserved.

ios-swift-connect-sample's People

Contributors

andrewjmay avatar bmitchell287 avatar jasonjoh avatar nokafor avatar o365devx avatar officegsx avatar ricalo avatar unpluggedk avatar v-dobr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ios-swift-connect-sample's Issues

Sample does not work for Microsoft Accounts

Confirmed that this sample does not work with MSAs. Works fine with O365 accounts.

Error returned is

ERROR unimplemented

Apparently this is fixed on Beta endpoint. Can the SDK switch to beta?

when i add bridge header file its getting error?.

when i run your sample app its working as expected but when i add pod to new project its getting error

MSGraphSDK.h file is not found

Failed to import bridging header'/Project_name/Project_Name-Bridging-Header.h'
_#import <MSGraphSDK.h> #import <MSGraphSDKNXOAuth2.h> #import <MSAuthConstants.h>_

In your pod file you are not using use_framework! for this and it generate a ibPods-Graph-iOS-Swift-Connect.a files in framework. For me it is not created. for me i need to use different cloud support so i need to use different pods.

Apple Review

After uploading the App to appstoreconnect,we receive this message:

ITMS-90809: Deprecated API Usage - Apple will stop accepting submissions of apps that use UIWebView APIs . See https://developer.apple.com/documentation/uikit/uiwebview for more information.

I checked, that box MSGraphSDK (MSAuthenticationViewController) is using UIWebView.
I think the Migrated from UIWebView to WKWebView is needed.

Crashing because of forced unwrap of nil value

Hi, I'm having issues with your sample, as it crashes every time I'm running it at this line.

https://github.com/microsoftgraph/ios-swift-connect-sample/blob/master/Graph-iOS-Swift-Connect/SendViewController.swift#L118

Probably, you are not counting for the nill values returned from the JSON and force unwrapping them. Any attempt to try to use guard or if let is futile.

Here's a sample of the data I received. This is the userInfo object.

{
    "@odata.context" = "https://graph.microsoft.com/v1.0/$metadata#users/$entity";
    businessPhones =     (
    );
    displayName = "<null>";
    givenName = "";
    id = 19c13xxxxxbf7;
    jobTitle = "<null>";
    mail = "<null>";
    mobilePhone = "<null>";
    officeLocation = "<null>";
    preferredLanguage = "<null>";
    surname = "";
    userPrincipalName = "nawar.a.nouri_gmail.com";
}

upload files in onedrive

Hurrah...Successfully can send mail. but i want to upload files in one drive. how can i do that please suggest me.

ERROR Error Domain=com.microsoft.graph.errors Code=500 "internal server error"

Hello, I'm getting the next error when I'm running the application:
ERROR Error Domain=com.microsoft.graph.errors Code=500 "internal server error" UserInfo={error= UnknownError : {"Status":500,"Message":"All the offeractions povided in the property bag cannot be validated for the token.\u000d\u000a"}, NSLocalizedDescription=internal server error}

The initial authentication is successful but this error is happening when the code is trying to retrieve users profile information.

Screenshot of the error stack trace

I'm using Xcode 9, swift 4, iOS11 on iPhone8 simulator.

Converted sample to Swift 3.0

Hello

I'm trying to convert this example to Swift 3.0 and I'm getting the following compile error:

/Users/brianriviere/ios-swift-connect-sample/Graph-iOS-Swift-Connect/Authentication.swift:40:35: Cannot convert value of type '(NSError?) -> ()' to expected argument type '((Error?) -> Void)!'

/Users/brianriviere/ios-swift-connect-sample/Graph-iOS-Swift-Connect/SendViewController.swift:65:46: Cannot convert value of type '([AnyHashable : Any]?, NSError?) -> ()' to expected argument type '(([AnyHashable : Any]?, Error?) -> Void)!'

/Users/brianriviere/ios-swift-connect-sample/Graph-iOS-Swift-Connect/SendViewController.swift:99:59: Cannot convert value of type '(MSGraphUser?, NSError?) -> ()' to expected argument type '((MSGraphUser?, Error?) -> Void)!'

Missing members

Hello I am trying to run this project using xcode 7 | ios 9.3

I am receiving these errors

Value of type 'NXOAuth2AuthenticationProvider' has no member 'loginSilent'

Type 'MSGraphClient' has no member 'defaultClient'

UPDATE:
Upon further inspection, I found that the 'loginSilent' is not implemented in this project.
I also found that 'defaultClient' didn't exist either.

After trying to fix these issues by taking methods out and fixing others I know get this error

ld: library not found for -lPods
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Please help!

[NSNull length] send to instance

While fetching email it crashes

   self.graphClient.me().request().getWithCompletion {
        (user: MSGraphUser?, error: Error?) in
       if let graphError = error {
       }
       else {
            DispatchQueue.main.async(execute: {
                
                if let eMail = userInfo.mail {
                    self.emailTextField.text = eMail
                }
            })
       }
  }

Need access to the Access Token

Hi there,
I've been trying to implement the procedure at this page Delegated User Identity with OAuth 2.0 On-Behalf-Of Draft Specification which provides to a daemon or a web application an access to resources on behalf of the user. However, as you can see in the reference, the access token obtained by the native application (the app) is sent to the web API/daemon.

The problem with this SDK is the access token (i.e. NXOAuth2AccessToken) is buried deep within the implementation and protected with no way to access it. Is there a remedy for this?

Thanks

when will planner and task be available?

Need it urgently to get planner and task integrated in project. According to my requirement, I need both of them to be integrated in project. Can you just let me know when it will be done.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.