Статьи

Поделитесь СМИ на Twitter, используя Flex, часть II: изображения

В первой части этой серии статей о совместном использовании мультимедиа в Twitter с помощью Flex мы обсуждали, как создать интерфейс для приложения Flex с помощью бета-версии Flash Catalyst. Затем мы использовали бета-версию Flash Builder 4 для создания приложения Twitter для браузера, который использовал PHP для прокси-вызовов для API Twitter. В этой статье мы собираемся улучшить это приложение Flex, добавив возможность загружать фотографии в популярный хостинг изображений Flickr, а затем интегрировать сокращенную ссылку на фотографию в сообщение в Twitter.

Когда вы закончите с учебником, проверьте свои знания, приняв нашу статью викторины !

Процесс загрузки

Загрузка фотографии и сокращение ее ссылки может быть сделано несколькими способами в приложении, которое мы создаем. Сначала необходимо загрузить изображение, получить ссылку на него, а затем отправить эту ссылку в службу сокращения URL-адресов. Если мы автоматизируем весь процесс таким образом, чтобы он работал, как только пользователь публикует свой твит, мы рискуем задержаться; это потому, что требуется три звонка на разные серверы. Вместо этого мы выбрали следующий процесс:

  1. пользователь загружает фото
  2. ссылка на фото вставлена ​​в конце твита в форму публикации
  3. сообщение отправляется пользователем

Весь код этой статьи содержится в новом файле cheepcheep_image_flashbuilder.fxp , и вы можете скачать его вместе со всеми ресурсами из предыдущей статьи .

Просмотр файлов

Класс ActionScript FileReference дает нам возможность загружать и скачивать файлы из приложения Flash. Его метод browse использует диалоговое окно операционной системы для поиска файла; каждый экземпляр FileReference будет ссылаться на один файл в системе пользователя. Убедитесь, что пространство имен добавлено для net в тег Application :

 <s:Application ...   xmlns:net="flash.net.*"/> 

Создайте экземпляр FileReference между тегами <fx:Declarations></fx:Declarations> уже имеющимися в приложении:

 <net:FileReference id="fileReference" select="fileSelected(event)" complete="fileAccessed(event)" /> 

Мы установили вызовы функций для его select и complete событий, которые мы добавим позже. Под полем TextInput для твита в нижней части приложения мы добавили кнопку; это позволяет нам искать файл для загрузки, и мы будем вызывать функцию browsePhoto , перечисленную ниже:

 private function browsePhoto(evt:MouseEvent):void {   var arr:Array = [];   arr.push(new FileFilter("Images", ".gif;*.jpeg;*.jpg;*.png"));   fileReference.browse(arr);  } 

Эта функция создает массив и заполняет его объектом FileFilter для ограничения расширений файлов, которые может выбрать пользователь. Затем он вызывает метод обзора экземпляра FileReference , передавая массив в качестве аргумента. Это запустит диалоговое окно операционной системы, которое откроет последний просмотренный каталог. Функция для события select будет запущена, как только пользователь select файл. Он загружает файл, который, в свою очередь, запускает событие complete , отображающее имя файла пользователю в нашем приложении. Это новый компонент Label который мы добавили рядом с кнопкой обзора. Вы можете использовать эту функцию, чтобы отобразить предварительный просмотр изображения, если требуется:

private function fileSelected(evt:Event):void { fileReference.load(); }

приватная функция fileAccessed (evt: Event): void {
fileName.text = «Файл выбран:» + fileReference.name;
}

Аутентификация с помощью Flickr

Существует ряд сервисов, которые размещают фотографии онлайн бесплатно. Мы выбрали Flickr, потому что у них есть хорошо документированный API, который уже имеет стороннюю библиотеку ActionScript . Flickr требует как аутентификации приложения, так и разрешения пользователя, прежде чем приложение сможет использовать его сервисы. Первый элемент, который вам понадобится, — это ключ API для вашего приложения, который вы можете получить бесплатно; ключ также будет иметь соответствующий «секрет» для аутентификации. Узнайте больше об этом здесь:

Библиотеку ActionScript 3 Flickr можно найти по адресу: http://code.google.com/p/as3flickrlib/ . Последняя сборка библиотеки не имеет метода для загрузки на Flickr, либо в библиотеке, либо в SWC. Несмотря на то, что в репозитории кода проекта есть версия метода загрузки, мы обнаружили проблемы в его работе. Мы предоставили копию библиотеки для проекта Flash Builder с рабочим методом загрузки; до сих пор это единственная часть библиотеки, где у нас возникли проблемы. Библиотека Flickr использует дополнительные MD5 и сетевые утилиты с http://code.google.com/p/as3corelib/, которые вам также необходимо загрузить, и мы включили SWC в проект Flash Builder.

Процесс аутентификации пользователя Flickr включает в себя несколько шагов программно, но он должен быть достаточно простым. В конечном итоге вам необходимо сгенерировать токен на Flickr для каждого отдельного пользователя вашего приложения и сохранять этот токен на компьютере пользователя для каждого вызова Flickr. Этот токен является безопасным представлением учетных данных пользователя; мы можем использовать его для выполнения таких задач, как наша загрузка, без необходимости знать эти учетные данные. Токен генерируется, когда пользователь дает разрешение вашему приложению на Flickr.

Мы собираемся использовать ActionScript SharedObject для локального хранения токена авторизации, а затем проверить, существует ли он, когда мы просматриваем файл. Мы попросим пользователя аутентифицировать приложение, если оно не существует, и напишем токен и идентификатор учетной записи пользователя, когда оно будет получено. Проверьте код ниже, и вы увидите, что мы импортируем необходимые классы из библиотеки Flickr, создавая экземпляр SharedObject и переменные для хранения нескольких значений, которые мы будем использовать в процессе аутентификации:

 import com.adobe.webapis.flickr.events.FlickrResultEvent;  import com.adobe.webapis.flickr.FlickrService;  import com.adobe.webapis.flickr.methodgroups.Auth;  import com.adobe.webapis.flickr.methodgroups.Upload;   private var appSO:SharedObject;   private var flickr:FlickrService;  private var flickrApiKey:String = "yourFlickrApiKey";  private var flickrSecret:String = "yourFlickrApiKeySecret";  private var flickrFrob:String = "";  private var flickrAuthToken:String = "";  private var flickrNsid:String = "";  private var authorizationURL:String = ""; 

В getFlickrLoginCredentials ниже функции getFlickrLoginCredentials мы пытаемся прочитать SharedObject для нашего приложения, создав его, если он не существует. Затем мы проверяем, был ли сохранен токен авторизации Flickr. Если его там нет, мы создаем экземпляр FlickrService , инициализируем его с помощью ключа API, добавляем секрет, назначаем обработчик и вызываем метод getFrob . Это вызывает Flickr для получения «frob», необходимого для получения токена авторизации — после того, как пользователь подключился к Flickr и предоставил разрешение на доступ к нашему приложению:

 public function getFlickrLoginCredentials():void {   appSO = SharedObject.getLocal("TestFlickrTwitter");   if ( appSO.data.flickrAuthToken == null ) {     flickr = new FlickrService(flickrApiKey);     flickr.secret = flickrSecret;     flickr.addEventListener( FlickrResultEvent.AUTH_GET_FROB, onGetFrob );     flickr.auth.getFrob();   } else {     flickrAuthToken = appSO.data.flickrAuthToken;     flickrNsid = appSO.data.flickrNsid;     browsePhoto();   }  } 

Другая половина функции getFlickrLoginCredentials является предложением else ; он считывает токен авторизации Flickr и идентификатор пользователя Flickr из SharedObject и вызывает метод browsePhoto который мы описали ранее. Мы изменили кнопку просмотра фотографии, чтобы вместо этого вызывать getFlickrLoginCredentials , чтобы мы getFlickrLoginCredentials пользователя в процессе аутентификации, если он попытается загрузить фотографию.

Ниже onGetFrob функция onGetFrob , обработчик результатов, вызываемый, когда мы получаем результат от вызова getFrob в функции выше. Это сохраняет «frob» как локальную переменную и создает URL авторизации, который понадобится позже:

 private function onGetFrob( evt:FlickrResultEvent ):void {   flickrFrob = evt.data.frob;   authorizationURL = flickr.getLoginURL(flickrFrob, "write");   currentState = "flickrAuthorise";  } 

Функция выше вызывает дополнительное состояние, которое мы создали для нашего приложения, называемое flickrAuthorise . Мы будем использовать это для отображения нового компонента, который мы создали в Flash Catalyst; этот компонент представляет собой всплывающее окно, содержащее сообщение для пользователя, объясняющее, что ему необходимо подключиться к Flickr для авторизации приложения. Компонент также содержит две кнопки: первая для открытия нового окна браузера и подключения к странице авторизации Flickr, а вторая — для получения токена авторизации из Flickr.

Вы заметите новое состояние, указанное в приложении:

 <s:states>   <s:State name="twitterLogin"/>   <s:State name="twitterDisplay"/>   <s:State name="flickrAuthorise"/>  </s:states> 

Посмотрите на визуальные объекты в приложении, и вы увидите различные атрибуты, используемые для управления ими в нескольких состояниях. Возьмите browsePhotoBtn , например; он использует атрибут includeIn чтобы includeIn в каких состояниях он будет отображаться. Также был установлен дополнительный атрибут для изменения альфа-канала кнопки для состояния flickrAuthorise чтобы он flickrAuthorise при появлении всплывающего окна авторизации. Большинство других визуальных объектов имеют такой же атрибут для того же эффекта:

 <s:Button x="180" y="670" label="Browse for Photo" click="getFlickrLoginCredentials()" id="browsePhotoBtn" includeIn="flickrAuthorise,twitterDisplay" alpha.flickrAuthorise="0.4"/> 

При нажатии на первую кнопку в нашем компоненте авторизации, CustomComponent2 , вызывается функция в главном приложении authoriseFlickr . Это открывает новое окно браузера, вызывающее URL авторизации, созданный внутри функции onGetFrob . Также включается вторая кнопка в компоненте авторизации:

 public function authoriseFlickr():void {   var urlRequest:URLRequest = new URLRequest(authorizationURL);   navigateToURL(urlRequest, "_blank");   customcomponent21.button3.enabled = true;  } 

Затем пользователь должен пройти пару шагов на сайте Flickr, чтобы авторизовать приложение. Последний экран, который они увидят, скажет им, что они могут закрыть окно браузера; затем они должны нажать на вторую кнопку на компоненте авторизации, который вызывает функцию onGetTockenClick в основном приложении. Это в свою очередь вызывает метод FlickrService для FlickrService . Функция-обработчик onGetToken указывается в функции onGetTockenClick . onGetToken получит объект от Flickr, содержащий токен авторизации и некоторые сведения о пользователе; мы используем эту функцию для локального хранения токена и идентификатора пользователя, а также в SharedObject . Мы также вернемся к основному состоянию twitterDisplay :

 public function onGetTokenClick():void {   flickr.addEventListener(FlickrResultEvent.AUTH_GET_TOKEN, onGetToken);   flickr.auth.getToken(flickrFrob);  }   private function onGetToken(evt:FlickrResultEvent):void {   flickrAuthToken = evt.data.auth.token;   flickrNsid = evt.data.auth.user.nsid;   appSO.data.flickrAuthToken = flickrAuthToken;   appSO.data.flickrNsid = flickrNsid;   appSO.flush();   currentState = "twitterDisplay";  } 

Это произойдет в первый раз, когда пользователь пытается найти фотографию, поэтому после проверки подлинности он должен будет просмотреть ее снова, поскольку этот шаг был прерван этим процессом. После того, как мы нашли нашу фотографию, нам нужно загрузить ее, чтобы мы могли включить ссылку на нее в наш твит.

Загрузка фото

Настроенный класс загрузки в библиотеке Flickr гарантирует, что вся необходимая аутентификация, процесс загрузки и событие загрузки завершены. Мы добавили кнопку внизу приложения под формой поста Twitter, чтобы загрузить изображение, и создали функцию для этой кнопки, которая называется uploadFlickr . Эта функция создает прослушиватель для события завершения загрузки и создает другой экземпляр класса FlickrService , добавляя к нему учетные данные. Затем он используется в качестве аргумента для экземпляра класса upload, который используется для загрузки нашего fileReference , который был создан, когда мы просматривали файл. Мы также добавили вызов метода setBusyCursor в CursorManager чтобы предоставить пользователю простую форму обратной связи во время загрузки — поскольку FlickrService не имеет этой функции:

 private function uploadFlickr():void {   fileReference.addEventListener(DataEvent.UPLOAD_COMPLETE_DATA,uploadCompleteHandler);   flickr = new FlickrService(flickrApiKey);   flickr.secret = flickrSecret;   flickr.token = flickrAuthToken;   var uploader:Upload = new Upload(flickr);   uploader.upload(fileReference);   CursorManager.setBusyCursor();  } 

При загрузке будет возвращен пакет XML от Flickr, содержащий идентификатор загруженного изображения, который мы можем использовать для создания ссылки для использования в нашем твите. С ограничением Twitter на 140 символов нам нужно управлять этим, так как URL-адреса Flickr, как правило, немного длинные. Мы собираемся обойти это, используя службу сокращения URL-адресов bit.ly , у которой есть REST API, который мы можем использовать в нашем приложении. Вам нужно будет создать учетную запись на bit.ly, чтобы получить ключ API; это автоматически выдается с учетной записью, с вашим ключом на странице сведений о вашей учетной записи.

Создание укороченной ссылки на изображение

uploadCompleteHandler указывается в качестве обработчика результатов в uploadFlickr и получит XML в свойстве data события. Мы преобразовываем это в объект XML в функции и создаем URL, объединяющий строку, идентификатор пользователя Flickr и идентификатор фотографии. Мы также создали переменные для хранения логина bit.ly и ключа API, которые необходимы для вызова остальных:

 [Bindable] private var photoUrl:String = "";  private var bitlyLogin:String = "yourBitlyAccountName";  private var bitlyApiKey:String = "yourBitlyApiKey";   private function uploadCompleteHandler(evt:DataEvent):void {   CursorManager.removeBusyCursor();   var xData:XML = new XML(evt.data);   photoUrl = "http://www.flickr.com/photos/"+flickrNsid+"/"+xData.photoid;   bitlyService.send();  } 

Функция uploadCompleteHandler вызывает метод send HTTPService после того, как адрес для изображения был создан. Помните, что тег HTTPService должен быть вложен в набор тегов <fx:Declarations> . Атрибут url тега HTTPService должен передавать в bit.ly ряд аргументов, все из которых связаны с переменными приложения. Мы установили обработчик для события result тега HTTPService :

 <mx:HTTPService id="bitlyService" method="GET" url="http://api.bit.ly/shorten?version=2.0.1&amp;longUrl={photoUrl}&amp;login={bitlyLogin}&amp;apiKey={bitlyApiKey}&amp;format=xml" result="bitlyService_resultHandler(event)"/> 

Мы разрешаем Flash Builder создавать обработчик по умолчанию для обработки результата bit.ly; сокращенный URL-адрес содержится в пакете XML, возвращаемом службой, который он преобразовал в объект ActionScript для нас. Функция вычисляет длину текста в настоящее время в поле TextInput для твита и либо добавляет сокращенный URL-адрес, либо обрезает текст, а затем добавляет URL-адрес:

 protected function bitlyService_resultHandler(evt:ResultEvent):void  {   var bitlyURL:String = evt.result.bitly.results.nodeKeyVal.shortUrl;   var combineTextURL:String = textinput1.text + " " + bitlyURL;   if ( combineTextURL.length < 140) {     textinput1.text = combineTextURL;   } else {     var excessChars:Number = 140 - combineTextURL.length;     textinput1.text = textinput1.text.substr(0,(textinput1.text.length)-Math.abs(excessChars)) + " " + bitlyURL;  }  } 

С загруженным изображением и созданной для него сокращенной ссылкой мы готовы завершить наш твит и опубликовать его в Twitter.

Загрузка непосредственно из приложения Flash была часто запрашиваемой функцией, представленной в Flash Player 9. Соединение изображений с текстом является большим улучшением для Twitter, и мы уверены, что вы захотите воспользоваться популярностью сервисов обмена фотографиями. как часть социального опыта, предоставленного вашей заявкой. Документация по Flickr API немного пугает непосвященных, особенно процесс аутентификации. К счастью, разработчикам доступны библиотеки ActionScript, которые облегчают процесс.

Вполне вероятно, что есть другие способы упорядочить процессы приложения, описанные в этой статье. Twitter не является универсальным магазином — их сервис создан для публикации минимальных текстовых сообщений. Мы рассчитываем на три сервисных звонка, чтобы сгенерировать наш единственный пост в Твиттере; Задача состоит в том, чтобы собрать их так, чтобы это было легко для пользователя, предлагая при этом разумное время производительности.

Убедитесь, что вы загрузили код для этой статьи и попробуйте.

Если вы чувствуете себя уверенно, проверьте свои знания, приняв нашу статью викторины !