Опубликован: 02.08.2013 | Доступ: свободный | Студентов: 464 / 17 | Длительность: 18:38:00
Специальности: Программист
Самостоятельная работа 9:

Работа с API веб-сервисов

Twitter

Рассмотрим приложение для выполнения поиска в Twitter, "Поиск в Twitter, пример использования бесконечной прокрутки в LongListSelector" (этот пример можно скачать здесь: http://code.msdn.microsoft.com/TwitterSearch-Windows-b7fc4e5e). Его особенность заключается в том, что оно взаимодействует с сервисом Twitter методами, не требующими авторизации, выполняя запросы к общедоступным механизмам службы. В частности, интересующая нас функциональность данного приложения (рис. 31.2.) реализована в файле TwitterViewModel.cs.

Приложение для поиска в Twitter

увеличить изображение
Рис. 31.2. Приложение для поиска в Twitter

В целом, приложение реализовано с помощью уже известного вам MVVM-подхода, в файле TwitterModel.cs определена структура данных, которая используется при формировании отдельного элемента, полученного от сервиса, TwitterViewModel (Листинг 16.1) – это модель представления, с помощью механизма привязки данных связанная с MainPage.xaml, где, записи выводятся в списке, с реализацией загрузки дополнительного содержимого при достижении последней записи, присутствующей в настоящий момент в списке

using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Net;
using System.ServiceModel.Syndication;
using System.Windows;
using System.Xml;
using TwitterSample.Model;

namespace TwitterSample.ViewModels
{
    public class TwitterViewModel:INotifyPropertyChanged
    {
        const string SEARCH_URI = "http://search.twitter.com/search.atom?q={0}&page={1}";

        private bool _isLoading = false;

        public bool IsLoading
        {
            get
            {
                return _isLoading;
            }
            set
            {
                _isLoading = value;
                NotifyPropertyChanged("IsLoading");

            }
        }       

        public TwitterViewModel()
        {
             this.TwitterCollection = new ObservableCollection<TwitterSearchResult>();
             this.IsLoading = false;
             
        }

        public ObservableCollection<TwitterSearchResult> TwitterCollection
        {
            get;
            private set;
        }

        public void LoadPage(string searchTerm, int pageNumber)
        {
            if (pageNumber == 1) this.TwitterCollection.Clear();

            IsLoading = true;
            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(new Uri
(String.Format(SEARCH_URI, searchTerm, pageNumber)));
       request.BeginGetResponse(new AsyncCallback(ReadCallback), request); 
        }        

        private void ReadCallback(IAsyncResult asynchronousResult)
        {
            try
            {
                HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
                HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
                using (StreamReader reader = new StreamReader(response.GetResponseStream()))
                {
                    //только для демонстрационных целей, не следует отправлять приложение 
на сертификацию с этой строкой.
                    System.Threading.Thread.Sleep(700);

                    NameTable nt = new NameTable();

                    XmlNamespaceManager nsmgr = new XmlNamespaceManager(nt);
                    nsmgr.AddNamespace("georss", "http://www.w3.org/2001/XMLSchema-instance");
                    XmlParserContext context = new XmlParserContext(null, nsmgr, null, XmlSpace.None);
                    XmlReaderSettings xset = new XmlReaderSettings();
                    xset.ConformanceLevel = ConformanceLevel.Fragment;


                    XmlReader rdr = XmlReader.Create(reader, xset, context);

                    SyndicationFeed feed = SyndicationFeed.Load(rdr);                    

                    Deployment.Current.Dispatcher.BeginInvoke(() =>
                    {

                        foreach (var item in feed.Items)
                        {

                            this.TwitterCollection.Add(new TwitterSearchResult()
                            {
                                Author = item.Authors[0].Name,
                                ID = GetTweetId(item.Id),
                                Tweet = item.Title.Text,
                                PublishDate = item.PublishDate.DateTime.ToLocalTime(),
                                AvatarUrl = item.Links[1].Uri.AbsoluteUri
                            });

                        }
                        IsLoading = false;
                    });

                }
            }
            catch (Exception e)
            {
                Deployment.Current.Dispatcher.BeginInvoke(() =>
                   {
                       MessageBox.Show("Network error occured " + e.Message);
                   });
            }
        }

        private string GetTweetId(string twitterId)
        {
            string[] parts = twitterId.Split(":".ToCharArray());

            return parts[2].ToString();
        }

        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged(String propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (null != handler)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}
Листинг 31.1. Файл TwitterViewModel.cs

Для выполнения запросов к службе используется URI следующего вида: http://search.twitter.com/search.atom?q={0}&page={1} (подробности о поиске в Twitter можно найти здесь: https://dev.twitter.com/docs/api/1.1/get/search/tweets, нужно учесть, что API как этого сервиса, так и других периодически обновляется, в частности, в API Twitter наблюдается переход от формата ATOM, который используется в данном примере для поиска, к формату JSON, в частности, для вызова операции поиска будет применятся ссылка следующего вида: https://api.twitter.com/1.1/search/tweets.json, дополнительные подробности можно найти здесь: https://dev.twitter.com/docs/using-search).

Вышеозначенная ссылка для доступа к службе используется при построении запроса для HttpWebRequest, который находится в методе LoadPage(), вызываемом из кода страницы MainPage.xaml. Разбор результатов запроса осуществляется в методе ReadCallBack().