Live SDKを使うとLive IDによるシングルサインオン、SkyDrive連携、Hotmailのカレンダー連携などが行えます。
また、Windows RuntimeやWindows Phone Runtimeからも使えます。
ダウンロードとインストール
Live SDKの最新版は執筆時点ではV5.3になっています。V5.3のダウンロードは以下のURLから行います。
http://www.microsoft.com/en-us/download/details.aspx?id=35754
Live SDKのインストールファイルはmsi形式なのでダウンロードしたファイルをダブルクリックすればインストールできます。
プロジェクトからの参照設定
アプリの登録
Live SDKを使ったアプリを作成するためには、Live Connect Developer Centerに登録が必要です。
また、Windowsストアアプリの場合、事前にWindows Store Dashboardでアプリ名の登録が完了していなければなりません。
Live Connect Developer Centerに登録すると、OAuth2.0でログインするときに必要なIDも入手できます。
しかし、Live SDKを使うとOAuth 2.0を意識することなくWindows 8にログインしたMicrosoftアカウントによるシングルサインオンが実現できます。
Live SDKによるシングルサインインの作成
Live SDKを使ってシングルサインインを実現するときも最初の1回だけアプリで明示的にログインが必要です。
次の例ではSignInAsync(False)で呼び出して(シングルサインインができていれば)ユーザ名を取得し、SignInAsync(True)で呼び出すことで明示的にサインインを行ってからユーザ名を取得するコードになります。
注意点は一度シングルサインインの設定が完了するとサインアウトができない点です。
Imports Microsoft.Live
Public Class AccountModel
Implements INotifyPropertyChanged
Private _UserName As String
Public Property UserName As String
Get
Return _UserName
End Get
Private Set(value As String)
_UserName = value
NotifyPropertyChanged()
End Set
End Property
Public Async Function SignInAsync(isLogin As Boolean) As Task
Dim client As New LiveAuthClient
Try
Dim result As LiveLoginResult = Await client.InitializeAsync()
If isLogin Then
result = Await client.LoginAsync(New String() {"wl.signin", "wl.basic", "wl.calendars"})
End If
If result.Status = LiveConnectSessionStatus.Connected Then
Dim connect As New LiveConnectClient(client.Session)
Dim data As LiveOperationResult = Await connect.GetAsync("me")
Me.UserName = data.Result("name").ToString
Else
Me.UserName = ""
End If
Catch ex As Exception
End Try
End Function
Public Async Function SignOutAsync() As Task
Dim client As New LiveAuthClient
Try
Dim result As LiveLoginResult = Await client.InitializeAsync()
If result.Status = LiveConnectSessionStatus.Connected Then
client.Logout()
End If
Me.UserName = ""
Catch ex As Exception
End Try
End Function
Public Event PropertyChanged(sender As Object,
e As PropertyChangedEventArgs) _
Implements INotifyPropertyChanged.PropertyChanged
Private Sub NotifyPropertyChanged(<CallerMemberName> Optional propertyName As String = Nothing)
RaiseEvent PropertyChanged(Me,
New PropertyChangedEventArgs(propertyName))
End Sub End Class
Liveでの用語は「サインイン」、「サインアウト」なんですがSDKのメソッド名はLogin、Logoutなんですよねー。
Live SDKによるシングルサインイン実行
[Sign in]ボタンをクリックするとSignInAsync(True)が呼び出され、client.LoginAsync(New String() {"wl.signin", "wl.basic", "wl.calendars"})を実行するので権限確認ダイアログが自動表示されます。
Microsoftアカウントページでの確認
Live SDKまたはOAuth2.0でLiveIDを使ってアプリにログインすると、Microsoftアカウントページの「Apps and services」のリストにアプリが追加されます。
https://account.live.com/consent/Manage
本来は日本語で表示されるのですが、私の普段使いのアカウントはなぜか英語認定されているため画面ハードコピーは英語表記だったりします。
LiveSDKによるイベント一覧の取得
サインインができたらLiveSDKでイベント(hotmailのカレンダー情報)を取得してみましょう。
Public Async Function GetDataAsync() As Task
Try Dim client As New LiveAuthClient
Dim result As LiveLoginResult = Await client.InitializeAsync()
result = Await client.LoginAsync(New String() {"wl.signin", "wl.basic", "wl.calendars"})
If result.Status = LiveConnectSessionStatus.Connected Then
Dim items As New List(Of TLiveEventItem)
Dim liveClient As New LiveConnectClient(result.Session)
Dim operationResult As LiveOperationResult = Await liveClient.GetAsync("me/events")
Dim events = operationResult.Result("data")
For index As Integer = 0 To events.Count - 1
If Not CType(events(index)("is_all_day_event"), Boolean) Then
items.Add(New TLiveEventItem With {
.id = events(index)("id").ToString,
.name = events(index)("name").ToString,
.description = events(index)("description").ToString,
.start_date = events(index)("start_time").ToString.Substring(0, 7),
.start_time = events(index)("start_time").ToString,
.end_time = events(index)("end_time").ToString,
.location = events(index)("location").ToString,
.is_all_day_event = CType(events(index)("is_all_day_event"), Boolean),
.reminder_time = CType(events(index)("reminder_time"), Integer)
})
End If
Next
Dim categories = _
From liveEvent In items
Where Not liveEvent.is_all_day_event
Group liveEvent By liveEvent.start_date Into eventCount = Count()
Select start_date
For Each category In categories
Dim group As New EventModelGroup(category,
category,
"",
"",
"")
Dim eventItems = From liveEvent In items
Where liveEvent.start_date = category
For Each item In eventItems
group.Items.Add(New EventModelItem(item.id,
item.name,
"",
"",
item.description,
"",
item.start_date,
item.start_time,
item.end_time,
item.location,
item.is_all_day_event,
group))
Next
Me._allGroups.Add(group)
Next
End If
Catch ex As Exception
Throw New Exception("Error posting data to LiveCalendar:" & ex.Message)
Finally
RaiseEvent Completed(Me._allGroups)
End Try
End Function
Public Event Completed(ByVal group As ObservableCollection(Of EventModelGroup))
LiveSDKによるイベント一覧取得の実行結果
このコードをWindowsストアアプリのテンプレートから作成したプロジェクトに組み込んだ実行結果は次のようになります。
OAuth2.0によるサインインの作成
Live SDKでのサインインの他にOAuth2.0でもLiveにサインインすることができます。こちらの方法はLive SDKのインストールや参照などは不要ですがLive SDKのように専用メソッドなどがある訳ではないので少しだけ手間がかかります。
Imports Windows.Security.Authentication.Web
Public Class AuthModel
Implements INotifyPropertyChanged
Private Const OAuth2Url As String = "https://oauth.live.com/authorize" &
"?client_id={0}" &
"&scope={1}" &
"&response_type=token" &
"&redirect_uri={2}" &
"×tamp={3}"
Public Property AccessToken As String
Get
Return Settings.AccessToken
End Get
Set(value As String)
Settings.AccessToken = value
Call NotifyPropertyChanged()
Call NotifyPropertyChanged("IsLogin")
End Set
End Property
Public ReadOnly Property IsLogin As Boolean
Get
Return (Settings.AccessToken IsNot Nothing)
End Get
End Property
Public ReadOnly Property AuthUrl As String
Get
Return String.Format(OAuth2Url,
Settings.ClientId,
"wl.signin%20wl.basic%20wl.calendars",
Settings.RedirectUrl,
Date.Now.ToString("yyyyMMddHHmmss"))
End Get
End Property
Public Async Function OAuthLogin() As Task
Dim loginUrl As String = AuthUrl
Dim result As WebAuthenticationResult =
Await WebAuthenticationBroker.AuthenticateAsync(
WebAuthenticationOptions.None,
New Uri(loginUrl),
New Uri(Settings.RedirectUrl))
If result.ResponseStatus = WebAuthenticationStatus.Success Then
Dim accessToken As String = result.ResponseData.ToString
Dim prefix As String = Me.CallbackPrefix
If accessToken.StartsWith(prefix) Then
accessToken = accessToken.Substring(prefix.Length)
If accessToken.IndexOf("&") >= 0 Then
accessToken = accessToken.Substring(0, accessToken.IndexOf("&"))
End If
Me.AccessToken = accessToken
End If
End If
End Function
Public ReadOnly Property CallbackPrefix As String
Get
Return Settings.RedirectUrl & "#access_token="
End Get
End Property
Public Event PropertyChanged(sender As Object,
e As PropertyChangedEventArgs) Implements INotifyPropertyChanged.PropertyChanged
Protected Sub NotifyPropertyChanged(<CallerMemberName> Optional propertyName As String = Nothing)
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
End Sub End Class
OAuth2.0によるサインイン実行
設定チャームの[アカウント]から直接OAuth2.0認証を呼び出しているのでサインインダイアログが表示されます。
[Sign In]ボタンをクリックすると権限確認ダイアログが自動表示されます。
以降はこの時に取得できたアクセストークンを使ってREST APIで情報を取得できます。
REST APIによるイベント一覧の取得
LiveSDKではなくREST APIでイベント(hotmailのカレンダー情報)を取得してみましょう。
Private Const CalendarsUrl As String = https://apis.live.net/v5.0/me/events?access_token={0}×tamp={1}
<DataContract()>
Private Class TEventResults
<DataMember(name:="data")>
Public Property data As List(Of TData)
End Class
<DataContract()>
Private Class TData
<DataMember(name:="id")>
Public Property id As String
<DataMember(name:="name")>
Public Property name As String
<DataMember(name:="description")>
Public Property description As String
<DataMember(name:="start_time")>
Public Property start_time As String
<DataMember(name:="end_time")>
Public Property end_time As String
<DataMember(name:="location")>
Public Property location As String
<DataMember(name:="is_all_day_event")>
Public Property is_all_day_event As Boolean
End Class
Public Async Function GetDataAsync() As Task
Dim urlString As String = String.Format(CalendarsUrl,
Settings.AccessToken,
Date.Now.ToString("yyyyMMddHHmmss"))
Try
Dim client As New HttpClient
Using response As HttpResponseMessage = Await client.GetAsync(urlString)
Dim responseDataStream As Stream = Await response.Content.ReadAsStreamAsync
Using stream As New MemoryStream()
responseDataStream.CopyTo(stream, responseDataStream.Length)
stream.Position = 0
Dim serializer As New System.Runtime.Serialization.Json.DataContractJsonSerializer(GetType(TEventResults))
Dim jsonDataValue As TEventResults = CType(serializer.ReadObject(stream), TEventResults)
Dim items As IEnumerable(Of TLiveEventItem) = _
From liveEvent In jsonDataValue.data
Where Not liveEvent.is_all_day_event
Select New TLiveEventItem With {
.id = liveEvent.id,
.name = liveEvent.name,
.description = liveEvent.description,
.start_date = liveEvent.start_time.Substring(0, 7),
.start_time = liveEvent.start_time,
.end_time = liveEvent.end_time,
.location = liveEvent.location,
.is_all_day_event = liveEvent.is_all_day_event
}
Dim categories = _
From liveEvent In items
Where Not liveEvent.is_all_day_event
Group liveEvent By liveEvent.start_date Into eventCount = Count()
Select start_date
For Each category In categories
Dim group As New EventModelGroup(category,
category,
"",
"",
"")
Dim eventItems = From liveEvent In items
Where liveEvent.start_date = category
For Each item In eventItems
group.Items.Add(New EventModelItem(item.id,
item.name,
"",
"",
item.description,
"",
item.start_date,
item.start_time,
item.end_time,
item.location,
item.is_all_day_event,
group))
Next
Me._AllGroups.Add(group)
Next
End Using
End Using
Catch ex As Exception
Throw New Exception("Error posting data to Foursquare:" & ex.Message)
Finally
RaiseEvent Completed(Me._allGroups)
End Try
End Function
Public Event Completed(ByVal group As ObservableCollection(Of EventModelGroup))
REST APIによるイベント一覧取得の実行結果
REST APIでの実行結果も当たり前ですがLive SDKのときと同じになります。