обзор
В моем предыдущем посте я дал вам обзор стартовых комплектов моей команды для приложений Магазина Windows. Я недавно взял World of Warcraft Starter Kit, который я сделал для Windows, который был написан на WinJS ( Windows Library for JavaScript ), и портировал его на Windows Phone.
Поскольку в настоящее время WinJS не доступен для Windows Phone, поэтому я решил написать собственное приложение Windows Phone для XAML / C #, а затем совершать сетевые вызовы с помощью элемента управления веб-браузера . Это тот же самый общий подход, который используется в шаблоне приложения Windows Phone HTML5 и других популярных инструментах, таких как Intel XDK .
В случае, если вы пропустили предыдущее сообщение, я решил выбрать API World of WarCraft от Blizzard, чтобы создать понятный пример приложения для отображения статуса Realm (это игровые серверы для World of Warcraft). Для тех, кто не в курсе, World of Warcraft — очень успешная онлайн-игра от Blizzard Entertainment®, предлагающая отличный открытый API для получения статистики игры. Полную документацию по API можно найти по адресу http://blizzard.github.io/api-wow-docs/ .
Вы можете загрузить версию Starter Kit для телефона здесь, на Github, и я также добавил ее в раздел Starter Kits этого блога.
В настоящее время я реализовал WOW API в двух основных функциональных возможностях в версии для Windows Phone.
- Статус Царства (индивидуальный)
- Статус Королевства (все)
Как и приложение для Магазина Windows, я хотел, чтобы версия Windows Phone служила работоспособным шаблоном приложения, чтобы помочь вашим собственным приложениям пройти сертификацию . Взяв за основу то, что я узнал из своих собственных приложений, я реализовал несколько функций, в которых разработчики не прошли сертификацию или столкнулись с ошибками во время разработки. Этот образец приложения включает в себя работоспособную функциональность для всего следующего:
- Панель приложений
- Страница настроек
- О странице
- Управление веб-браузером
- Веб-задачи
- Вызов HTML5 / JS из C #
- Маленькие и средние плитки
Требования
- Windows 8
- Visual Studio 2012 Express для Windows Phone или выше
Настроить
- Загрузите Zip-портфолио Starter Kit с веб-сайта ( http://apimash.github.io/StarterKits/ ).
- Откройте решение в Visual Studio
- Скомпилируйте и запустите
настройка
Шаг 1. Всем API Blizzard World of Warcraft не требуется ключ разработчика для использования. Однако, если вы планируете создать приложение с интенсивным использованием API, Blizzard просит вас связаться с ним по адресу [email protected], чтобы зарегистрировать ваше приложение.
Шаг 2. В настоящее время реализован только статус области. Добавить дополнительную функциональность, такую как информация о персонаже или PvP, так же просто, как вызвать соответствующий wow api (находится в http://blizzard.github.io/api-wow-docs/ ), а затем обернуть его в функцию так же, как статус области Это было сделано в /html/js/wowapi.js и / html / js / getRealmStatus.
Файл Wowapi.js содержит вызов функции для получения всех статусов области, а затем сгенерировал группу тегов div внутри элемента div в /html/index.html с именем divStatus. В версии Магазина Windows мы использовали преобразователи данных WinJS, чтобы изменить значение цветов в столбцах списка. Для этой версии мы используем простой CSS, чтобы закрасить фон каждого div.
"use strict"; function getRealmStatusAll() { $.getJSON("http://us.battle.net/api/wow/realm/status?jsonp=?", function (data) { $.each(data.realms, function (i, item) { //Add some padding between the server name cells var bgPadding = 'padding-top: 30px;padding-bottom: 30px;'; //Check status of realm and convert background to green for online and red for offline var bgStyle = item.status === true ? 'background-color: green;' : 'background-color: red;'; //Set up div style and show server text var divText = "<div style='' + bgPadding + bgStyle + "'><p>" + item.name + "<p></div><p>"; //Add new div to main divStatus div $(divText).appendTo("#divStatus"); }); }); } function onLoad() { //tmp until buttons included getRealmStatusAll(); }
GetRealmStatus.js следует соглашению, аналогичному wowapi.js, но за исключением того, что теперь мы примем аргумент для одного сервера. Этот аргумент будет фактически передан в функцию JavaScript из кода C #, в котором размещен элемент управления веб-браузера.
"use strict"; function getRealmStatus(realm) { $.getJSON("http://us.battle.net/api/wow/realm/status?realm=" + realm + "&jsonp=?", function (data) { $.each(data.realms, function (i, item) { //Add some padding between the server name cells var bgPadding = 'padding-top: 30px;padding-bottom: 30px;'; //Check status of realm and convert background to green for online and red for offline var bgStyle = item.status === true ? 'background-color: green;' : 'background-color: red;'; //Set up div style and show server text var divText = "<div style='' + bgPadding + bgStyle + "'><p>" + item.name + "<p></div><p>"; //Add new div to main divStatus div $(divText).appendTo("#divStatus"); }); }); //alert(realm); //To Test args }
Шаг 3 . Теперь, когда мы настроили сетевые вызовы (с минимальными изменениями по сравнению с нашей версией WinJS для Магазина Windows), нам нужен какой-то способ для отображения генерируемого HTML.
Здесь мы возьмем элемент управления веб-браузера и скажем ему загрузить соответствующий контент.
Мы также используем здесь флаг для того, какой тип данных нам нужно отображать (все или отдельные области). Эти флаги устанавливаются в области приложения и доступны на всех страницах приложения. Поэтому, когда пользователь устанавливает новый сервер для отслеживания, мы сразу увидим эти изменения.
// Url of Home page private string uriRealmsAll = "/Html/index.html"; private string uriRealmsSingle = "/Html/realmStatus.html"; // Constructor public MainPage() { InitializeComponent(); InitSettings(); Browser.IsScriptEnabled = true; } //Get server settings private void InitSettings() { if (App.appSettings.Contains("realm")) { App.userRealm = (string)App.appSettings["realm"]; } else { App.userRealm = App.defaultRealm; App.appSettings.Add("realm", App.defaultRealm); } } private void Browser_Loaded(object sender, RoutedEventArgs e) { if (App.allRealms) { Browser.Navigate(new Uri(uriRealmsAll, UriKind.Relative)); } else { Browser.Navigate(new Uri(uriRealmsSingle, UriKind.Relative)); } } private void btnAbout_Click(object sender, System.EventArgs e) { NavigationService.Navigate(new Uri("/About.xaml", UriKind.Relative)); } private void btnSettings_Click(object sender, System.EventArgs e) { NavigationService.Navigate(new Uri("/RealmSettings.xaml", UriKind.Relative)); } private void btnRealm_Click(object sender, System.EventArgs e) { App.allRealms = false; Browser.Navigate(new Uri(uriRealmsSingle, UriKind.Relative)); } private void btnAllRealms_Click(object sender, System.EventArgs e) { App.allRealms = true; Browser.Navigate(new Uri(uriRealmsAll, UriKind.Relative)); } private void Browser_LoadCompleted(object sender, NavigationEventArgs e) { if (!App.allRealms) { Browser.IsScriptEnabled = true; String[] realm = new String[1]; realm[0] = HttpUtility.UrlEncode(App.userRealm); Browser.InvokeScript("getRealmStatus", realm[0]); } }
Вы заметите, что мы передаем флаг имени сервера самому элементу управления Web Browser с помощью метода InvokeScript . Это позволяет нам генерировать взаимодействие с пользователем в нашем собственном пользовательском интерфейсе на основе XAML, а затем передавать аргументы функциям JavaScript, которые мы загружаем в элемент управления веб-браузера.
Здесь следует отметить две вещи: во-первых, у вас должен быть включен сценарий для элемента управления через флаг IsScriptEnabled, а во-вторых, вам нужно будет дождаться вызова функции JavaScript, как только весь контент будет загружен в DOM. Я решил сделать это через событие LoadCompleted элемента управления.
Шаг 4. Когда вы добавите больше функций в свое собственное приложение, вы захотите включить страницу «О программе» и «Настройки». Оба они настроены с использованием собственных элементов управления XAML.
Страница О программе будет передана в WebBrowserTask, если пользователь решит получить больше информации.
XAML:
<Grid x:Name="LayoutRoot" Background="Transparent"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <!--TitlePanel contains the name of the application and page title--> <StackPanel Grid.Row="0" Margin="12,17,0,28"> <TextBlock Text="{StaticResource app_title}" Style="{StaticResource PhoneTextNormalStyle}"/> <TextBlock Text="about" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/> </StackPanel> <StackPanel x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> <TextBlock x:Name="txtAbout" HorizontalAlignment="Center" TextWrapping="Wrap" Text="The World of Warcraft Windows Phone 8 API Starter Kit is a completely free app for educational and entertainment purposes only. The code for this app is open source and available on Github. " VerticalAlignment="Top" Height="108" Width="446" /> <Button x:Name="btnGithub" Content="Download Source Code" Margin="0,40" Click="btnGithub_Click"/> <TextBlock x:Name="txtAbout2" HorizontalAlignment="Center" TextWrapping="Wrap" Text="For more information aout my other free apps, developer starter kits, and online training courses check out my blog DaveDev.net." VerticalAlignment="Top" Height="108" Width="446" /> <Button x:Name="btnBlog" Content="Visit DaveDev.net" Margin="0,0,0,40" Click="btnBlog_Click"/> </StackPanel>
C #:
private void btnGithub_Click(object sender, RoutedEventArgs e) { WebBrowserTask webBrowserTask = new WebBrowserTask(); webBrowserTask.Uri = new Uri("http://github.com/apimash", UriKind.Absolute); webBrowserTask.Show(); } private void btnBlog_Click(object sender, RoutedEventArgs e) { WebBrowserTask webBrowserTask = new WebBrowserTask(); webBrowserTask.Uri = new Uri("http://davedev.net", UriKind.Absolute); webBrowserTask.Show(); }
На странице настроек будет храниться любое имя сервера, которое вводит пользователь, а затем использовать его для …
XAML:
<Grid x:Name="LayoutRoot" Background="Transparent"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <!--TitlePanel contains the name of the application and page title--> <StackPanel Grid.Row="0" Margin="12,17,0,28"> <TextBlock Text="{StaticResource app_title}" Style="{StaticResource PhoneTextNormalStyle}"/> <TextBlock Text="settings" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/> </StackPanel> <!--ContentPanel - place additional content here--> <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> <StackPanel Margin="10,58,-10,339" Orientation="Vertical"> <TextBlock HorizontalAlignment="Left" TextWrapping="Wrap" Text="My Realm" Margin="10,0,0,0" FontSize="24" /> <TextBox x:Name="txtRealm" HorizontalAlignment="Left" Height="72" TextWrapping="Wrap" Width="406"/> <Button x:Name="btnSave" Content="Save" HorizontalAlignment="Left" Width="152" Height="91" Click="btnSave_Click" /> </StackPanel> </Grid> </Grid>
C #:
public partial class RealmSettings : PhoneApplicationPage { public RealmSettings() { InitializeComponent(); InitUserSettings(); } private void InitUserSettings() { if (App.appSettings.Contains("realm")) { txtRealm.Text = (string)App.appSettings["realm"]; } } private void btnSave_Click(object sender, System.Windows.RoutedEventArgs e) { if (App.appSettings.Contains("realm")) { App.appSettings["realm"] = txtRealm.Text; } else { App.appSettings.Add("realm", txtRealm.Text); } var result = MessageBox.Show("Your Realm has been updated to '" + txtRealm.Text + "'.", "Changes Saved", MessageBoxButton.OK); App.allRealms = false; NavigationService.Navigate(new Uri("/MainPage.xaml", UriKind.Relative)); } }
Вывод
Надеемся, что этот набор поможет вам в разработке собственных приложений для Windows Phone. Не забудьте проверить остальные мои стартовые наборы, а также полный проект APIMASH здесь.
-Dave