문서를 영문으로 보려면 영문 확인란을 선택하세요. 마우스 포인터를 텍스트 위로 이동시켜 팝업 창에서 영문 텍스트를 표시할 수도 있습니다.
번역
영문

Create a Cordova App using O365 Outlook Services and Ionic

Visual Studio 2013

이 자습서에서는 O365 Outlook 서비스 및 Ionic 프레임워크를 사용하여 메일, 일정 및 연락처 클라이언트를 만드는 방법을 배웁니다. 이 앱을 사용하여 사용자는 O365 Outlook 서비스 API를 통해 메일, 일정 및 연락처에 액세스할 수 있습니다. 이 샘플은 JavaScript 코드를 사용하지만 TypeScript에서 Cordova 앱을 작성할 수도 있습니다.

이 자습서에서는 다음 단계를 수행합니다.

  1. 프로젝트 만들기

  2. 프로젝트에 Ionic 프레임워크 추가

  3. 프로젝트에 NProgress 추가

  4. 앱에 O365 서비스 추가

  5. O365 메일, 일정 및 연락처에 사용 권한을 설정하여 앱에 대해 적절한 액세스 권한 부여

  6. Ionic 컨트롤을 사용하여 앱 폴더 구조, UI 라우팅 및 레이아웃 만들기

  7. AngularJS 팩터리를 사용하여 액세스 토큰 획득 및 Outlook 서비스 클라이언트 받기

  8. O365 API를 사용하여 Outlook 서비스 데이터 가져오기 :

    • 메일 앱의 경우, 중요로 플래그가 지정된 메일, 읽지 않은 메일 및 모든 메일

    • 일정 앱의 경우, 오늘의 모임(이벤트 시작 날짜가 오늘과 같음), 내일의 모임(이벤트 시작 날짜가 내일과 같음) 및 시작 날짜가 오늘과 같거나 오늘 이후인 모든 이벤트

    • 연락처 앱의 경우, 모든 연락처

  9. O365 API를 사용하여 데이터 생성 및 삭제 :

    • 메일, 일정 이벤트 삭제

    • 새 일정 이벤트, 연락처 만들기

  10. 앱 실행

다음 스크린샷은 완료되었을 때 실행 중인 일정 앱을 보여 줍니다.

다음 스크린샷은 완료되었을 때 실행 중인 메일 앱을 보여 줍니다.

다음 스크린샷은 완료되었을 때 실행 중인 연락처 앱을 보여 줍니다.

새 프로젝트를 만들기 전에 모든 시스템 요구 사항이 충족되었으며 Visual Studio용 Visual Studio Tools for Apache Cordova 확장을 설치했는지 확인합니다. 자세한 내용은 Visual Studio Tools for Apache Cordova 설치를 참조하세요.

파일, 새 프로젝트, JavaScript, Apache Cordova 앱, 새 응용 프로그램 템플릿을 차례로 선택하여 Visual Studio에서 새 Cordova 프로젝트를 만듭니다.

Ionic 프레임워크를 추가하려면

  1. Ionic 프레임워크에서 웹사이트을 선택하고 Download beta를 선택합니다.

  2. zip 파일의 압축을 풉니다.

  3. Visual Studio의 솔루션 탐색기에서 Cordova 프로젝트 아래에 lib라는 새 폴더를 만들고 lib 폴더에 압축을 푼 내용을 복사합니다.

  4. 스크립트 참조를 업데이트합니다.

    Index.html의 <head> 요소에서 Cordova 및 platformOverrides 스크립트 참조 뒤에 다음 Ionic 참조를 추가합니다.

    <script src="lib/ionic/js/ionic.bundle.min.js"></script>
    

    Index.html에서 다음 ionic CSS 참조를 추가합니다.

    <link href="lib/ionic/css/ionic.min.css" rel="stylesheet" />
    

NProgress는 O365에서 메일, 일정 및 연락처를 가져오는 동안 진행률 표시줄을 표시하는 데 사용됩니다.

프로젝트에 NProgress를 추가하려면

  1. NProgress 웹사이트에서 Download를 선택합니다.

  2. zip 파일의 압축을 풉니다.

  3. 솔루션 탐색기의 lib 폴더 아래에 nprogress라는 폴더를 만들고 nprogress.js를 폴더에 복사합니다.

  4. css 폴더에 nprogress.css 복사

  5. index.html에서 <head> 요소에 다음 NProgress 참조를 추가합니다.

    <link href="css/nprogress.css" rel="stylesheet" />
    <script src="lib/nprogress/nprogress.js"></script>
    

Office 365 개발자 사이트에 등록하고 Office 365 개발 환경 설정(영문)에 있는 지침에 따라 개발자 사이트에 대한 Azure Active Directory 액세스를 설정합니다.

개발자 사이트를 설정한 후 아래 단계에 따라 Visual Studio의 서비스 관리자를 사용하여 Office 365 API를 추가하고 구성합니다.

Office 365 API를 추가하고 구성하려면

  1. Visual Studio 갤러리에서 Office 365 API 도구(영문)를 다운로드하고 설치합니다.

  2. 프로젝트 노드의 바로 가기 메뉴에서 추가를 선택한 다음 연결된 서비스를 선택합니다.

  3. 서비스 관리자 대화 상자 위쪽에서 Office 365 링크를 선택한 다음 앱 등록을 선택합니다.

    Office 365 개발자 조직에 대한 테넌트 관리자 계정으로 로그인합니다.

O365 계정에 로그인하면 해당 테넌트 계정에 메일, 일정, 연락처 및 파일 등과 같은 O365 서비스의 목록이 나타납니다. 각 액에 대해 아래에 지정된 것처럼, 앱에서 사용하려는 서비스를 선택하고 앱에서 액세스할 권한을 설정합니다.

Dn911025.collapse_all(ko-kr,VS.120).gif메일 앱

메일을 선택하고 오른쪽 창에서 권한... 링크를 클릭합니다. 그런 다음 앱이 메일 읽기 및 삭제 작업을 수행해야 하므로 사용자의 메일 읽기 및 쓰기를 선택합니다. 마찬가지로, 앱에서 메일을 보내려면 메일을 사용자 옵션으로 선택합니다.

Dn911025.collapse_all(ko-kr,VS.120).gif일정 앱

일정을 선택하고 오른쪽 창에서 권한... 링크를 클릭한 다음 have full access to users' calendar(사용자의 일정에 대해 모든 권한 부여)를 선택합니다. 마찬가지로, 앱에 읽기 권한만 부여하려면 Read users' calendar(사용자의 일정 읽기)를 선택합니다.

Dn911025.collapse_all(ko-kr,VS.120).gif연락처 앱

연락처를 선택하고 오른쪽 창에서 권한... 링크를 클릭한 다음 have full access to users' contact(사용자의 연락처에 대해 모든 권한 부여)를 선택합니다. 마찬가지로, 앱에 읽기 권한만 부여하려면 Read users' contact(사용자의 연락처 읽기)를 선택합니다.

Dn911025.collapse_all(ko-kr,VS.120).gif변경 내용 적용 및 참조 업데이트

변경 내용을 적용하고 참조를 업데이트하려면

  1. 적용확인을 차례로 클릭하여 권한을 설정하고 프로젝트에 O365 API를 추가합니다.

    서비스 관리자가 프로젝트에 서비스 폴더를 추가합니다.

  2. index.html에서 <head> 요소에 다음 O365 참조를 추가합니다.

    <script src="services/office365/scripts/o365loader.js"></script>
    <script src="services/office365/settings/settings.js"></script>
    

다음 단계에 따라 앱 UI와 JavaScript 코드를 구성합니다.

프로젝트 루트 노드에 app이라는 폴더를 만듭니다. app 폴더에는 앱과 관련된 파일이 들어갑니다. UI에 데이터를 가져오고 바인딩하는 각 UI 구성 요소에는 해당 컨트롤러가 있습니다(UI 다음에 패턴 뒤 코드가 있음). 예를 들어 mail-list.html은 목록 컨트롤을 표시하여 사용자의 메일을 표시하고, mail-list-ctrl.js는 O365 API를 사용하여 사용자의 메일을 가져오는 코드가 들어 있습니다.

다음은 프로젝트의 폴더 및 파일에 대한 자세한 내용입니다.

  • auth 폴더에는 로그인 및 로그아웃에 대한 UI 및 코드가 들어 있습니다.

  • layout 폴더에는 ion-pane, ion-side-menus, ion-nav-bar 같은 앱 내용과 탐색을 표시하는 UI와 사용자 이름을 바인딩하는 코드가 들어 있습니다.

  • app.js에는 다른 페이지를 탐색하는 UI 라우팅이 들어 있습니다.

  • service-o365.js에는 액세스 토큰을 가져오고, Outlook 서비스 클라이언트 개체를 만들고, 로그아웃하고, 사용자 이름을 가져오는 유틸리티 함수가 들어 있습니다. service-o365.js는 이러한 함수가 여러 페이지에서 유틸리티 함수로 노출될 수 있도록 AngularJS 팩터리로 구현됩니다.

AngularJS 라우팅을 사용하여 다른 페이지를 탐색합니다. 예를 들어, 다음은 메일 앱에 대한 라우팅입니다.

// Layout page
    .state('app', {
        abstract: true,
        url: "/app",
        templateUrl: "app/layout/layout.html"
    })

    // Sign-in page
     .state('sign-in', {
         url: "/sign-in",
         templateUrl: "app/auth/sign-in.html"
     })

    // Sign-out page
        .state('app.sign-out', {
            url: "/sign-out",
            views: {
                'mainContent': {
                    templateUrl: "app/auth/sign-out.html"
                }
            }
        })   

    // Mail list page
    .state('app.mail', {
        url: "/mail",
        views: {
            'mainContent': {
                templateUrl: "app/mail/mail-tabs.html"
            }
        }
    })

    // Mail list containing mails flagged as important
    .state('app.mail.imp', {
        url: "/imp/id:important",
        views: {
            "tab-imp-mail": {
                templateUrl: "app/mail/mail-list.html"
            }
        }
    })

    // Mail detail page
    .state('app.mail-detail', {
        url: "/mail/:id",
        views: {
            'mainContent': {
                templateUrl: "app/mail/mail-detail.html"
            }
        }
    })

    // Unread mail list page
    .state('app.mail.unread', {
        url: "/unread/id:unread",
        views: {
            "tab-unread-mail": {
                templateUrl: "app/mail/mail-list.html"
            }
        }
    })

    // All mail list page
    .state('app.mail.all', {
        url: "/all/id:all",
        views: {
            "tab-all-mail": {
                templateUrl: "app/mail/mail-list.html"
            }
        }
    });

    // Navigate to sign-in page when app starts.
    $urlRouterProvider.otherwise('sign-in');

앱 레이아웃(메뉴, 탐색 도구 모음)의 경우 Ionic 측면 메뉴 및 창을 사용합니다.

<ion-side-menus ng-controller="layoutCtrl as vm">

    <ion-pane ion-side-menu-content>
        <ion-nav-bar class="bar-positive">
            <ion-nav-back-button class="button-clear icon ion-ios7-arrow-back"></ion-nav-back-button>
            <button menu-toggle="left" class="button button-icon icon ion-navicon"></button>
        </ion-nav-bar>
        <ion-nav-view name="mainContent" animation="slide-left-right"></ion-nav-view>
    </ion-pane>

    <ion-side-menu side="left">
        <header class="bar bar-header bar-positive">
            <h1 class="title">{{vm.userName}}</h1>
        </header>
        <ion-content class="has-header">
            <ion-list>                            
                <ion-item nav-clear menu-close ui-sref="app.sign-out">Sign-out</ion-item>
            </ion-list>
    </ion-side-menu>

</ion-side-menus>

Ionic 탭을 사용하여 별도의 탭에 여러 콘텐츠를 표시합니다. 예를 들어, 아래의 Ionic 컨트롤을 사용하여 중요 메일, 읽지 않은 메일 및 모든 메일을 다른 탭에 표시할 메일 탭 페이지를 만듭니다.

<ion-view>
    <ion-tabs class="tabs-positive tabs-icon-top">
        <ion-tab title="Imp" icon="ion-star" ui-sref="app.mail.imp">
            <ion-nav-view name="tab-imp-mail"></ion-nav-view>
        </ion-tab>

        <ion-tab title="Unread" icon="ion-ios7-email-outline" ui-sref="app.mail.unread">
            <ion-nav-view name="tab-unread-mail"></ion-nav-view>
        </ion-tab>

        <ion-tab title="All" icon="ion-email" ui-sref="app.mail.all">
            <ion-nav-view name="tab-all-mail"></ion-nav-view>
        </ion-tab>
    </ion-tabs>
</ion-view>

다음 그림에서는 메일 탭 페이지를 보여 줍니다.

AngularJS 팩터리를 만들어 O365 API를 노출하고 액세스 토큰을 받고, Outlook 서비스 클라이언트를 만들고, 로그아웃하고, 앱의 다른 컨트롤러에서 사용하는 다른 유틸리티 함수를 수행합니다.

액세스 토큰을 획득하는 코드는 다음과 같습니다.

var authContext = new O365Auth.Context();
authContext.getIdToken("https://outlook.office365.com/")
.then((function (token) {
     // Get auth token
     authtoken = token;
     // Get user name from token object.
     userName = token.givenName + " " + token.familyName;
    }), function (error) {
      // Log sign-in error message.
      console.log('Failed to login. Error = ' + error.message);
 });

Outlook 서비스 클라이언트 개체를 만드는 코드는 다음과 같습니다.

var outlookClient = new Microsoft.OutlookServices.Client('https://outlook.office365.com/api/v1.0', authtoken.getAccessTokenFn('https://outlook.office365.com'));

O365 API를 노출하는 전체 AngularJS 팩터리 코드는 다음과 같습니다.

(function () {
    'use strict';
    angular.module('app365').factory('app365api', [app365api]);

    function app365api() {

        var authContext;
        var authtoken;
        var outlookClient;      
        var userName;

        // Login to O365
        function login(callback) {
            if (!authContext) {
                authContext = new O365Auth.Context();
            }

            authContext.getIdToken("https://outlook.office365.com/")
           .then((function (token) {
               // Get auth token
               authtoken = token;
               // Get user name from token object.
               userName = token.givenName + " " + token.familyName;
               // Create Outlook client object.
               outlookClient = new Microsoft.OutlookServices.Client('https://outlook.office365.com/api/v1.0', authtoken.getAccessTokenFn('https://outlook.office365.com'));
               // Callback without parameter to indicate successful sign-in.
               callback();
           }), function (error) {
               // Log sign-in error message.
               console.log('Failed to login. Error = ' + error.message);
               callback(error.message);
           });
        };

        // Logout
        function logout() {
            if (!authContext) {
                authContext = new O365Auth.Context();
            }

            authContext.logOut();
        };

        // Get signed-in user name.
        function getUserName() {
            return userName;
        };

        return {
            login: login,
            logout: logout,
            getUserName: getUserName,        
            exchangeClientObj: function () { return outlookClient; }
        };
    };
})();


Outlook 클라이언트 개체를 사용하여 메일, 일정 및 연락처에서 읽기 및 쓰기 작업을 수행할 수 있습니다.

Dn911025.collapse_all(ko-kr,VS.120).gifOutlook 클라이언트 개체를 사용하여 메일, 일정 및 연락처 읽기

다음 코드는 중요로 플래그가 지정된 모든 메일을 읽습니다.

// Get all mails flagged as important.
function getImpMails() {
   NProgress.start();
   // Filter to fetch all important mails received after 2000-10-20
   var filterQuery = "Importance eq 'High' and DateTimeReceived gt 2000-10-20";
   outlookClient.me.folders.getFolder("Inbox").fetch()
   .then(function (folder) {
   // Fetch all important mails sorted by DateTimeReceived.
      folder.messages.getMessages().filter(filterQuery).orderBy('Importance,DateTimeReceived desc').fetch()
.then(function (mails) {
// Get current page. Use getNextPage() to fetch next set of mails.
vm.mails = mails.currentPage;
$scope.$apply();
NProgress.done();
}, function (error) {
    console.log("Error encountered while fetching mails. Error: " + error.message);
 });
}, function (error) {
    console.log("Error encountered while fetching inbox folder. Error: " + error.message);
  });
};


다음 코드는 시작 날짜가 오늘과 같은 모든 이벤트를 읽습니다.

var filterQuery = 'start gt ' + today.toISOString() + ' and start lt ' + tomorrow.toISOString();
NProgress.start();
// Get events with filter.
outlookClient.me.calendar.events.getEvents().filter(filterQuery).fetch()
.then(function (events) {
// Get current page. Use getNextPage() to fetch next set of events.
    vm.events = events.currentPage;
    $scope.$apply();
    NProgress.done();
});

다음 코드는 모든 연락처를 읽습니다.

function getContacts() {
NProgress.start();

// Fetch all the contacts.
outlookClient.me.contacts.getContacts().fetch()
.then(function (contacts) {
// Get the current page. Use getNextPage() to fetch next set of contacts.
    vm.contacts = contacts.currentPage;
    $scope.$apply();
    NProgress.done();
  });
};

Dn911025.collapse_all(ko-kr,VS.120).gifOutlook 클라이언트 개체를 사용하여 메일 및 일정 이벤트 삭제

Outlook 클라이언트 개체를 사용하여 메일을 삭제할 수 있습니다. 메일을 삭제하려면 메일 ID를 사용하여 삭제할 메일을 가져온 다음 메일 개체에서 delete()을 호출하여 특정 메일을 삭제합니다.

참고 참고

delete()은 메일을 영구적으로 삭제합니다. 메일을 삭제된 항목으로 이동하려면 대신 move()를 사용합니다.

메일을 삭제하는 코드는 다음과 같습니다.

// Fetch the mail with specified mail id.                    outlookClient.me.folders.getFolder("Inbox").messages.getMessage(mail.id).fetch()
.then(function (mail) {
    // Delete the mail.
    mail.delete()
    .then((function (response) {
         // mail deleted successfully.                
     }), function (error) {                            
         // Log the error message when error is encountered while deleting the mail.
         console.log('fail to delete mail. Error = ' + error.message);
 });

이벤트를 삭제하는 코드는 다음과 같습니다.

// Fetch event with specified event id.
outlookClient.me.calendar.events.getEvent(event.id).fetch()
.then(function (event) {
    // Delete event.
    event.delete()
    .then((function (response) {                            
     // Refresh event list.
     }).bind(this), function (reason) {
     // Log delete event error.
     console.log('Fail to delete event. Error = ' + reason.message);
});


Dn911025.collapse_all(ko-kr,VS.120).gifOutlook 클라이언트 개체를 사용하여 새 연락처 및 일정 이벤트 만들기

Outlook 클라이언트 개체를 사용하여 새 연락처와 일정 이벤트를 만들고 메일을 보낼 수 있습니다.

새 일정 이벤트를 추가하는 코드는 다음과 같습니다.

// Event body content
var eventBody = new Microsoft.OutlookServices.ItemBody();
eventBody.contentType = Microsoft.OutlookServices.BodyType.HTML;
eventBody.content = $scope.newEvent.body;
// Event attendee.
var attendee = new Microsoft.OutlookServices.Attendee();
// Attendee email address.
var emailAddress = new Microsoft.OutlookServices.EmailAddress();
emailAddress.address = $scope.newEvent.toRecipients;
attendee.emailAddress = emailAddress;
// Event object.
var event = new Microsoft.OutlookServices.Event();
// Event start date.
event.start = new Date($scope.newEvent.start).toISOString();
// Event end date time
event.end = new Date($scope.newEvent.end).toISOString();
// Event subject.
event.subject = $scope.newEvent.subject;
// Event body.
event.body = eventBody;
// Add event attendee.
event.attendees.push(attendee);
// Event location.
event.location = new Microsoft.OutlookServices.Location();
event.location.displayName = 'Sample Location';
// Add event
outlookClient.me.calendar.events.addEvent(event)
.then((function (response) {
// New event created successfully.
})
.bind(this), function (reason) {
// Log the error message encountered while adding the event.
console.log('Fail to add event. Error = ' + reason.message);
});


새 연락처를 추가하는 코드는 다음과 같습니다.

// Contact object
var contact = new Microsoft.OutlookServices.Contact();

// First and last name
contact.givenName = $scope.newContact.firstname;
contact.surname = $scope.newContact.lastname;

// Mobile phone
contact.mobilePhone1 = $scope.newContact.phone;

// Email address
var emailAddress = new Microsoft.OutlookServices.EmailAddress();
emailAddress.address = $scope.newContact.email;
contact.emailAddresses.push(emailAddress);

// Add Contact
outlookClient.me.contacts.addContact(contact)
.then((function (response) {
// Contact added successfully.

})
.bind(this), function (reason) {
// Log the error message when add contact fails.
console.log('Fail to add contact. Error = ' + reason.message);
});

대상 OS로 Android를 선택하고 Android 에뮬레이터 또는 Android 장치에 배포합니다.

참고 참고

Ripple은 현재 O365 인증에 대해 지원되지 않습니다.

F5 키를 눌러 앱을 실행합니다.

다른 플랫폼에서 Cordova 앱 실행에 대한 자세한 내용은 Visual Studio Tools for Apache Cordova를 사용하여 빌드한 앱 배포 및 실행을 참조하세요.

전체 응용 프로그램은 Github(영문)에서 다운로드할 수 있습니다. 샘플 앱을 다운로드하고 시험해 본 후 어떻게 생각하는지 알려 주세요. Visual Studio의 새 O365 API 및 Cordova 도구 지원에 대한 의견을 듣고 싶습니다!

설명

Cordova 일정 앱 (영문)

Ionic을 사용하여 만든 샘플 Cordova 앱으로 이벤트 읽기, 필터링, 삭제 및 추가에 대해 O365 일정 API를 사용하는 방법을 보여 줍니다. (1) 오늘의 이벤트, (2) 내일의 이벤트, (3) 시작 날짜가 오늘과 같거나 오늘 이후인 모든 이벤트의 3개 그룹으로 이벤트를 분류합니다.

Cordova 메일 앱 (영문)

Ionic을 사용하여 만든 샘플 Cordova 앱으로 메일 읽기, 필터링 및 삭제에 대해 O365 메일 API를 사용하는 방법을 보여 줍니다. (1) 중요, (2) 읽지 않음, (3) 모든 메일의 3개 그룹으로 사용자 메일을 분류합니다.

Cordova 연락처 앱 (영문)

Ionic을 사용하여 만든 샘플 Cordova 앱으로 연락처 읽기 및 추가에 대해 O365 연락처 API를 사용하는 방법을 보여 줍니다.

표시: