обзор
В моем предыдущем посте я дал вам обзор стартовых комплектов моей команды для приложений Магазина 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 просит вас связаться с ним по адресу api-support@blizzard.com, чтобы зарегистрировать ваше приложение.
Шаг 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