• Ввойдите на сайт >>>

Статьи

Как написать простой веб-сервис PHP / MySQL для приложения для iOS

  1. Что ты сделаешь
  2. Создание базы данных
  3. Проверка работоспособности PHP / MySQL
  4. Стратегия веб-сервиса: ПОЛУЧИТЬ против ПОЧТЫ
  5. Стратегия веб-сервиса: алгоритм
  6. Реализация веб-сервиса
  7. Куда пойти отсюда?

Правило веб-сервисов!

Как разработчику iPhone / iPad, может быть очень полезно иметь возможность создавать свои собственные простые веб-сервисы, которые интегрируются с вашими приложениями.

Например, вы можете отображать некоторые новости, поступающие с вашего веб-сервера, и отображать их при запуске. Или, возможно, хранить некоторые пользовательские данные «в облаке». Ваше воображение - единственный предел!

В этом первом уроке из этой серии из двух частей вы шаг за шагом пройдете процесс создания простого веб-сервиса на основе системы промо-кодов, которую я включил в свое последнее приложение. Дикие басни , В следующей части этой серии вы напишите приложение для iOS, которое интегрируется с этим веб-сервисом!

Чтобы выполнить все шаги этого руководства, вам понадобится веб-сервер с MySQL и PHP. Если у вас еще нет веб-сервера, у вас есть три варианта:

  • Если вы хотите включить Apache / MySQL / PHP непосредственно на вашем Mac (бесплатно), есть много хороших руководств, вот один я нашел с быстрым поиском Google.
  • Если вы хотите арендовать веб-сервер онлайн (обычно за $$), есть много хороших вариантов, но я лично использую (и наслаждаюсь) Linode - проверьте этот урок для дополнительной информации.
  • И если вам просто лень делать что-либо из вышеперечисленного, вы можете просто прочитать описанные ниже шаги и использовать веб-сервис, который я уже сделал во второй части серии:]

Вам не обязательно знать PHP или MySQL, чтобы пройти этот учебник (хотя он будет полезен!), Так как учебник включает весь необходимый вам код.

Что ты сделаешь

Как вы уже знаете, если вы добавили Покупки в приложении В вашем приложении нет встроенной системы, предоставляемой Apple для выдачи промо-кодов для покупок в приложении.

Однако может быть очень полезно создать собственную систему промо-кодов для покупок в приложении по нескольким причинам:

  1. Во-первых, замечательно иметь возможность выдавать промо-коды для контента покупок в приложении профессиональным рецензентам приложений.
  2. Во-вторых, также приятно иметь возможность выдавать промо-коды своим друзьям, чтобы они могли проверить ваше приложение.
  3. Наконец, если вы построите свою систему правильно, это также предоставляет отличный способ отследить, какие из ваших маркетинговых векторов окупаются (а какие нет) - подробнее об этом во второй части серии!

Таким образом, в этом руководстве мы собираемся создать систему, в которой вы можете ввести код в свое приложение, и оно подключится к веб-службе, чтобы проверить, является ли код действительным или нет. Если он действителен, приложение «разблокирует» некоторый контент.

Не беспокойтесь, если у вас нет планов по добавлению этой конкретной системы в ваше приложение - вы изучите общую технику разработки веб-службы и интеграции ее с приложением для iPhone!

Создание базы данных

Первым шагом этого проекта является создание таблиц базы данных, которые вам понадобятся. Для целей этого урока вам понадобятся три таблицы базы данных:

  • rw_app : таблица для отслеживания приложений, для которых мы используем систему промо-кодов. Таким образом, вы можете использовать одни и те же таблицы базы данных для нескольких приложений.
    • id : уникальный идентификатор приложения.
    • app_id : уникальная строка, идентифицирующая приложение (в основном для ваших собственных целей).
  • rw_promo_code : таблица для отслеживания доступных промо-кодов.
    • id : уникальный идентификатор для кода.
    • rw_app_id : идентификатор приложения, для которого предназначен этот код (из rw_app).
    • code : буквенно-цифровой код, который пользователь вводит для разблокировки.
    • unlock_code : буквенно-цифровая строка, которую вы передадите обратно в приложение, чтобы оно могло знать, что разблокировать.
    • used_remaining : вы настроите так, чтобы коды можно было использовать более одного раза - таким образом, вы можете раздавать один и тот же код всем нашим друзьям в Twitter, например. Вы будете использовать это поле, чтобы указать, сколько раз должен использоваться код, и каждый раз, когда он используется, он будет уменьшаться на единицу. Когда iti достигает 0, код больше не действителен.
  • rw_promo_code_redeemed : таблица для отслеживания некоторой информации каждый раз, когда промо-код погашается. Это поможет нам не допустить, чтобы одно устройство использовало один и тот же код несколько раз (если это многоцелевой код), просто проверив, использовало ли устройство этот код.
    • id : уникальный идентификатор приложения.
    • rw_promo_code_id : идентификатор промо-кода погашен (из rw_promo_code).
    • device_id : идентификатор устройства получателя .
    • redeemed_time : отметка времени, когда код был погашен.

Вот операторы MySQL, которые вам понадобятся для создания этих таблиц:

DROP TABLE ЕСЛИ СУЩЕСТВУЕТ rw_promo_code; DROP TABLE ЕСЛИ СУЩЕСТВУЕТ rw_app; DROP TABLE ЕСЛИ СУЩЕСТВУЕТ rw_promo_code_redeemed; CREATE TABLE rw_promo_code (id mediumint NOT NULL AUTO_INCREMENT ПЕРВИЧНЫЙ КЛЮЧ, rw_app_id tinyint NOT NULL, код varchar (255) NOT NULL, unlock_code varchar (255) NOT NULL, использует_основную smallint НЕ НУЛЬ); CREATE TABLE rw_app (id mediumint NOT NULL AUTO_INCREMENT PRIMARY KEY, app_id varchar (255) NOT NULL); CREATE TABLE rw_promo_code_redeemed (id mediumint NOT NULL AUTO_INCREMENT ПЕРВИЧНЫЙ КЛЮЧ, rw_promo_code_id mediumint NOT NULL, device_id varchar (255) NOT NULL, выкуплено время timeESTAMP DEFAULT CURRENT_TIMESTAMP ONDATE

На вашем веб-сервере вам нужно создать базу данных MySQL и создать три таблицы, как указано выше. То, как вы это делаете, варьируется в зависимости от вашего веб-хостинга, но на всякий случай полезно рассказать вам о шагах, которые я использую на своем веб-хосте, где у меня есть полный доступ из командной строки.

Я сохраняю все вышеприведенные операторы SQL в файл с именем create.sql, затем создаю и заполняю новую базу данных следующими командами:

rwenderlich @ kermit: ~ $ mysql -u root -p Введите пароль: Добро пожаловать в монитор MySQL. Команды заканчиваются на; или \ g. Идентификатор соединения с MySQL: 1286 Версия сервера: 5.1.37-1ubuntu5.1-log (Ubuntu). Введите 'help;' или '\ h' за помощь. Введите «\ c», чтобы очистить текущий оператор ввода. mysql> создать базу данных промо; Запрос в порядке, 1 строка затронута (0,00 сек.) Mysql> use promos; База данных изменена: mysql> предоставляет все привилегии для рекламных акций. * На «username» @ «localhost», идентифицируемый как «password»; Запрос в порядке, 0 строк затронуты (0,00 с) mysql> выход Пока rwenderlich @ kermit: ~ $ mysql -u username -p promos <create.sql Введите пароль: rwenderlich @ kermit: ~ $ mysql -u root -p Введите пароль: Добро пожаловать на монитор MySQL. Команды заканчиваются на; или \ g. Идентификатор соединения с MySQL: 1417 Версия сервера: 5.1.37-1ubuntu5.1-log (Ubuntu). Введите 'help;' или '\ h' за помощь. Введите «\ c», чтобы очистить текущий оператор ввода. mysql> использовать промо; База данных изменена MySQL> Показать таблицы; + ------------------------ + | Tables_in_promos | + ------------------------ + | rw_app | | rw_promo_code | | rw_promo_code_redeemed | + ------------------------ + 3 строки в наборе (0,00 сек)

Теперь у вас должно быть три пустых таблицы базы данных в новой базе данных. Далее, добавьте тестовое приложение и тестовый код со следующими утверждениями:

INSERT INTO rw_app VALUES (1, 'com.razeware.test'); INSERT INTO ЗНАЧЕНИЯ rw_promo_code (1, 1, 'test', 'com.razeware.test.unlock.cake', 10000);

ХОРОШО! Теперь, когда база данных подключена и заполнена, приступим к написанию веб-сервиса PHP!

Проверка работоспособности PHP / MySQL

Прежде чем приступить к реализации веб-службы PHP, сначала запустите быструю проверку, чтобы убедиться, что PHP работает на вашем сервере, и все в порядке. Создайте новый каталог на вашем веб-сервере с именем promos и создайте новый файл с именем index.php со следующим:

<? php class RedeemAPI {// Основной метод для использования кода функции redeem () {echo "Hello, PHP!&quot;; }} // Это первое, что вызывается при загрузке этой страницы // Создает новый экземпляр класса RedeemAPI и вызывает метод redeem $ api = new RedeemAPI; $ API-> выкупить (); ?>

Это очень простой PHP-файл, который создает экземпляр класса (RedeemAPI) и вызывает для него метод, который просто выводит «Hello, PHP!»

Вы можете проверить это, перейдя по URL на вашем веб-сервере в браузере. Более того, вы можете проверить это в командной строке с помощью удобной утилиты curl, аналогичной следующей (но замените URL-адрес своим собственным):

Ray-Wenderlichs-Mac-mini-2: ~ rwenderlich $ curl http://www.wildfables.com/promos/ Привет, PHP!

Затем расширьте класс, чтобы убедиться, что служба может подключиться к вашей базе данных, и замените класс RedeemAPI следующим:

class RedeemAPI {private $ db; // Конструктор - открыть функцию соединения с БД __construct () {$ this-> db = new mysqli ('localhost', 'username', 'password', 'promos'); $ This-> db-> автокоммит (FALSE); } // Деструктор - закрыть функцию соединения с БД __destruct () {$ this-> db-> close (); } // Основной метод для выкупа кода функция redeem () {// Распечатать все коды в базе данных $ stmt = $ this-> db-> prepare ('SELECT id, code, unlock_code, использует_remaining FROM rw_promo_code'); $ Stmt-> Execute (); $ stmt-> bind_result ($ id, $ code, $ unlock_code, $ used_remaining); while ($ stmt-> fetch ()) {echo "у $ code осталось $ use_remaining Использования, которое осталось!"; } $ stmt-> close (); }}

Это добавляет конструктор, который подключается к вашей базе данных с указанием имени пользователя и пароля, и деструктор, который закрывает соединение с базой данных. Цикл восстановления используется для запуска оператора MySQL, чтобы выбрать все записи в rw_promo_code, и выполнить цикл, чтобы напечатать строку о каждой записи.

Еще раз вы можете проверить это с помощью curl, чтобы убедиться, что он работает:

Ray-Wenderlichs-Mac-mini-2: ~ rwenderlich $ curl http://www.wildfables.com/promos/ test - осталось 10000 использований!

Стратегия веб-сервиса: ПОЛУЧИТЬ против ПОЧТЫ

Хорошо, теперь, когда мы знаем, что все работает, почти пришло время реализовать полное поведение. Но сначала давайте поговорим о нашей стратегии для веб-сервиса.

Мы знаем, что нам нужно передать некоторые данные из приложения iPhone в наш веб-сервис. В частности, нам нужно сообщить веб-службе идентификатор приложения, код для погашения и идентификатор устройства, которое пытается использовать.

Но как мы можем передать эти данные? Если вы еще не знакомы, есть два способа передачи данных в веб-службу - через GET (обычный способ) или через POST (обычно используется для публикации данных в веб-форме).

В зависимости от того, что вы выберете, параметры передаются по-разному:

  • Если вы выбираете GET , параметры являются частью URL.
  • Если вы выбираете POST , параметры передаются как часть тела запроса.

Либо один из них будет работать, но обычно, когда вы пытаетесь «сделать что-то», например, использовать код (а не просто пассивно извлекать данные), вы выбираете метод POST, поэтому мы собираемся сделать это здесь.

Что это значит на практике? Все это означает, что если мы хотим получить доступ к переданным параметрам в PHP, мы получаем их из встроенного массива $ _POST следующим образом:

$ _POST [ "rw_app_id"]

И когда мы используем ASIHTTPRequest для подключения к веб-службе позже, мы будем использовать класс ASIFormDataRequest, который отправляет запрос в виде POST следующим образом:

ASIFormDataRequest * request = [ASIFormDataRequest requestWithURL: url]; [request setPostValue: @ "1" forKey: @ "rw_app_id"];

Для получения дополнительной информации о GET против POST, проверьте Википедия по протоколу HTTP.

Обновление: Кроме того, проверьте комментарий @ smpdawg в тема форума для этого урока некоторые дополнительные обязательные к прочтению советы и информация об этом!

Стратегия веб-сервиса: алгоритм

Далее давайте рассмотрим общий алгоритм, который примет веб-сервис:

  1. Убедитесь, что необходимые параметры передаются через POST.
  2. Убедитесь, что код на самом деле находится в базе данных.
  3. Удостоверьтесь, что код все еще использует оставшиеся.
  4. Убедитесь, что устройство еще не использовало код.
  5. Если мы получили это далеко, успехов!
    • Добавьте запись в rw_promo_code_redeemed для отслеживания погашения.
    • Уменьшите использование_представления в rw_promo_code.
    • Верните unlock_code в приложение, чтобы оно могло предоставлять контент пользователю.

Хорошо, теперь, когда у нас есть стратегия на реализацию!

Реализация веб-сервиса

Во-первых, добавьте два вспомогательных метода в начало вашего PHP-файла, которые вы будете использовать, чтобы легко возвращать HTTP-сообщения о состоянии в случае успеха и неудачи:

// Вспомогательный метод для получения описания строки для кода состояния HTTP // От http://www.gen-x-design.com/archives/create-a-rest-api-with-php/ function getStatusCodeMessage ($ status ) {// они могут быть сохранены в файле .ini и загружены // через parse_ini_file () ... однако этого будет достаточно // для примера $ codes = Array (100 => 'Continue', 101 => ' Протоколы переключения ', 200 => «OK», 201 => «Создан», 202 => «Принят», 203 => «Неавторизованная информация», 204 => «Нет контента», 205 => «Сбросить контент» , 206 => «Частичное содержимое», 300 => «Несколько вариантов выбора», 301 => «Постоянно перемещено», 302 => «Найдено», 303 => «Просмотреть другое», 304 => «Не изменено», 305 = > «Использовать прокси», 306 => «(Не используется)», 307 => «Временное перенаправление», 400 => «Неверный запрос», 401 => «Несанкционированный», 402 => «Требуется оплата», 403 => ' Запрещено », 404 =>« Не найдено », 405 =>« Метод не разрешен », 406 =>« Недопустимо », 407 =>« Требуется проверка подлинности прокси », 408 =>« Тайм-аут запроса », 409 =>« Конфликт » ', 410 =>' Ушел ', 411 =>' Требуется длина red ', 412 => «Предварительное условие не выполнено», 413 => «Слишком большой объект запроса», 414 => «Слишком длинный запрос-URI», 415 => «Неподдерживаемый тип носителя», 416 => «Запрошенный диапазон не удовлетворен» , 417 => «Ожидание не выполнено», 500 => «Внутренняя ошибка сервера», 501 => «Не реализовано», 502 => «Плохой шлюз», 503 => «Служба недоступна», 504 => «Тайм-аут шлюза», 505 => «HTTP-версия не поддерживается»); возврат (isset ($ codes [$ status]))? $ code [$ status]: ''; } // Вспомогательный метод для отправки кода ответа HTTP / функция сообщения sendResponse ($ status = 200, $ body = '', $ content_type = 'text / html') {$ status_header = 'HTTP / 1.1'. $ статус. ''. getStatusCodeMessage ($ статус); заголовок ($ status_header); заголовок ('Content-type:'. $ content_type); echo $ body; }

Если вы не уверены, зачем нам это нужно, поскольку это веб-служба, соответствующая протоколу HTTP, при отправке ответа вы можете указать заголовок, в котором указан любой код ошибки и описание, которое происходит. Существуют стандартные коды ошибок, которые можно использовать, поэтому эти методы облегчают работу.

Как вы можете видеть, я нашел функцию для преобразования кодов состояния в сообщения HTML из большого учебника по создание REST API с PHP ,

Далее на фактическую реализацию! Замените свой метод погашения следующим:

function redeem () {// Проверка необходимых параметров if (isset ($ _ POST ["rw_app_id"]) && isset ($ _ POST ["code"]) && isset ($ _ POST ["device_id"])) {// Put параметры в локальные переменные $ rw_app_id = $ _POST ["rw_app_id"]; $ code = $ _POST ["code"]; $ device_id = $ _POST ["device_id"]; // Поиск кода в базе данных $ user_id = 0; $ stmt = $ this-> db-> prepare ('SELECT id, unlock_code, использует_remaining FROM rw_promo_code WHERE rw_app_id =? AND code =?'); $ stmt-> bind_param ("is", $ rw_app_id, $ code); $ Stmt-> Execute (); $ stmt-> bind_result ($ id, $ unlock_code, $ used_remaining); while ($ stmt-> fetch ()) {break; } $ stmt-> close (); // Залог, если код не существует if ($ id <= 0) {sendResponse (400, 'Неверный код'); вернуть ложь; } // Залог, если код уже используется if ($ used_remaining <= 0) {sendResponse (403, «Код уже использован»); вернуть ложь; } // Проверяем, было ли это устройство погашено $ stmt = $ this-> db-> prepare ('ВЫБЕРИТЕ id ИЗ rw_promo_code_redeemed WHERE device_id =? AND rw_promo_code_id =?'); $ stmt-> bind_param ("si", $ device_id, $ id); $ Stmt-> Execute (); $ Stmt-> bind_result ($ redeemed_id); while ($ stmt-> fetch ()) {break; } $ stmt-> close (); // Залог, если код уже погашен if ($ redeemed_id> 0) {sendResponse (403, «Код уже использован»); вернуть ложь; } // Добавить отслеживание погашения $ stmt = $ this-> db-> prepare ("INSERT INTO rw_promo_code_redeemed (rw_promo_code_id, device_id) VALUES (?,?)"); $ stmt-> bind_param ("is", $ id, $ device_id); $ Stmt-> Execute (); $ Stmt-> близко (); // Уменьшаем использование кода $ this-> db-> query ("UPDATE rw_promo_code SET sets_remaining = used_remaining-1 WHERE id = $ id"); $ This-> db-> совершить (); // Возвращаем код разблокировки, закодированный в JSON $ result = array ("unlock_code" => $ unlock_code,); sendResponse (200, json_encode ($ result)); вернуть истину; } sendResponse (400, «Неверный запрос»); вернуть ложь; }

Вы должны быть в состоянии понять общую идею о том, как все работает здесь, посмотрев на комментарии, встроенные в код, и, если вам интересно, посмотрите Mysqli ссылка , Кроме того, вот несколько вещей, на которые я хотел бы обратить внимание:

  • isset - это удобная функция в PHP, которую вы можете использовать, чтобы узнать, установлена ​​ли конкретная переменная. Мы используем его здесь, чтобы убедиться, что все необходимые параметры POST переданы.
  • Обратите внимание, что вместо того, чтобы сами добавлять переданные переменные в оператор SQL, мы используем для этого метод bind_param. Это гораздо более безопасный способ, иначе вы становитесь уязвимыми для SQL-инъекция атака.
  • Обратите внимание, что код unlock_code возвращается в кодировке JSON. Это правда, что мы могли бы передать это как необработанную строку или так далее, поскольку мы возвращаем только одну вещь, но с помощью JSON это облегчает расширение позже.

И это все - ваш веб-сервис готов к работе! Вы можете проверить это с помощью следующей команды curl:

curl -F "rw_app_id = 1" -F "code = test" -F "device_id = test" http://www.wildfables.com/promos/ {"unlock_code": "com.razeware.wildfables.unlock.test" }

Обратите внимание, что если вы пытаетесь сделать это на моем веб-сервисе, если вы получаете сообщение об ошибке «код уже используется», вы должны изменить свой device_id (поскольку каждый из них может использоваться только один раз!)

Вы также можете зайти в свою базу данных и проверить, есть ли запись в вашей таблице rw_promo_code_redeemed, что значение use_remaining уменьшилось и т. Д. Поиграйте с этим немного!

Куда пойти отсюда?

Здесь исходный код для веб-сервиса, который мы разработали в приведенном выше руководстве.

Следите за следующим учебником из этой серии, в котором мы покажем, как создать приложение для iPhone, которое интегрируется с этим веб-сервисом, а также обсудим мой опыт использования этой системы промо-кода в Дикие басни !

Если у вас есть какие-либо вопросы по поводу этого учебного пособия или советов другим пользователям, создающим веб-службы для приложений iPhone, присоединяйтесь к обсуждению на форуме ниже!

Quot;; }} // Это первое, что вызывается при загрузке этой страницы // Создает новый экземпляр класса RedeemAPI и вызывает метод redeem $ api = new RedeemAPI; $ API-> выкупить (); ?
Но как мы можем передать эти данные?
Что это значит на практике?
SELECT id, unlock_code, использует_remaining FROM rw_promo_code WHERE rw_app_id =?
AND code =?
ВЫБЕРИТЕ id ИЗ rw_promo_code_redeemed WHERE device_id =?
AND rw_promo_code_id =?
Куда пойти отсюда?

Новости

Карта