В детстве я постоянно поглощал Marvel Comics. В последнее время с появлением регулярных фильмов Marvel вновь появился интерес к вселенной Marvel. Marvel любезно выпустил API, который разрешил доступ ко всем вещам от их персонажей до комиксов и событий. В этой статье будет показано, как получить доступ к Marvel API из приложения iOS, написанного на Swift.
Первое, что вам нужно сделать, это зарегистрировать аккаунт разработчика на http://developer.marvel.com/ . Это даст вам открытые / закрытые ключи и доступ к их документации. Ключи необходимы для доступа к API.
Моей отправной точкой было ванильное iOS-приложение «Single View» Я использовал cocoapods для настройки зависимостей. Для этого приложения я решил использовать SwiftHttp для HTTP-коммуникаций и JSONJoy-Swift, чтобы отобразить ответ JSON обратно в структуру Swift.
Мой подфайл выглядит так.
source 'https://github.com/CocoaPods/Specs.git' platform :ios, '8.1' pod 'SwiftHTTP', :git => "https://github.com/daltoniam/SwiftHTTP.git", :tag => "0.9.1" pod 'JSONJoy-Swift', :git => "https://github.com/daltoniam/JSONJoy-Swift.git", :tag => "0.9.1"
После настройки я добавил простой вид iOS с UIImageView и кнопкой загрузки.
Что будет делать приложение, нажав кнопку загрузки, мы получим доступ к API, загрузим подробную информацию о «Человеке-муравье» и установим его эскиз в виде изображения.
1. Мы получим доступ к информации о «Человеке-муравье» через API персонажа комиксов. Чтобы получить его данные, мы отправим HTTP-запрос GET на http://gateway.marvel.com:80/v1/public/characters/ с несколькими параметрами:
- его имя
- API-ключ (открытый ключ)
- ts (временная метка или значение, которое изменяется за запрос)
- хеш (md5 хэш ts + открытый ключ + закрытый ключ)
Более подробную информацию об API можно найти здесь
2. Определите IBAction для кнопки загрузки. В рамках действия мы создадим HTTP-запрос и начнем загрузку.
@IBAction func download(sender: AnyObject) { }
Добавьте оператор импорта в начало файла ViewController.
import SwiftHTTP import JSONJoy
Для создания HTTP-запроса нам нужно создать HTTPTask. Наша первая итерация метода будет выглядеть следующим образом.
@IBAction func download(sender: AnyObject) { let name = "Ant-Man" let url = "http://gateway.marvel.com:80/v1/public/characters" var request = HTTPTask() let publicKey = "YOUR PUBLIC KEY" let ts = NSDate().timeIntervalSince1970.description request.GET(url, parameters: ["nameStartsWith": name, "apikey": publicKey, "ts" : ts], success: { (response: HTTPResponse) -> Void in println("got a response: \(response.responseObject)") },{(error: NSError, response: HTTPResponse?) -> Void in println("got an error: \(error)") }) }
Заполните ваш открытый ключ открытым ключом из вашей учетной записи разработчика. Мы используем параметр nameStartsWith для извлечения Ant-Man
3. Запрос не будет работать, если мы не хешируем закрытый ключ и не передадим его в качестве параметра. Для этого потребуется применить хеш MD5 к временной метке, объединенной с открытым ключом и закрытым ключом. Для выполнения хеширования MD5 в Swift я использовал эту суть, которая расширяет класс String для добавления метода MD5.
Итак , создайте файл с именем «Swift-MD5.swift» и добавить содержимое сути там. Вам нужно будет добавить файл заголовка моста в importCommonCrypto / CommonCrypto.h, который необходим для хеширования MD5.
Мы можем создать хеш для нашего запроса сейчас.
let publicKey = "YOUR PUBLIC KEY" let privateKey = "YOUR PRIVARE KEY" let ts = NSDate().timeIntervalSince1970.description let hash = "\(ts)\(privateKey)\(publicKey)".md5()
4. Собирая все вместе, наша функция загрузки будет выглядеть так:
@IBAction func download(sender: AnyObject) { let name = "Ant-Man" let url = "http://gateway.marvel.com:80/v1/public/characters" var request = HTTPTask() let publicKey = "YOUR PUBLIC KEY" let privateKey = "YOUR PRIVARE KEY" let ts = NSDate().timeIntervalSince1970.description let hash = "\(ts)\(privateKey)\(publicKey)".md5() request.GET(url, parameters: ["nameStartsWith": name, "apikey": publicKey, "ts" : ts], success: { (response: HTTPResponse) -> Void in println("got a response: \(response.responseObject)") },{(error: NSError, response: HTTPResponse?) -> Void in println("got an error: \(error)") }) }
Запуск приложения и нажатие кнопки загрузки инициирует запрос. Это приведет к выводу текста, как показано ниже в консоли.
got a response: Optional({ attributionHTML = "<a href=\"http://marvel.com\">Data provided by Marvel. \U00a9 2015 MARVEL</a>"; attributionText = "Data provided by Marvel. \U00a9 2015 MARVEL"; code = 200; copyright = "\U00a9 2015 MARVEL"; data = { count = 2; limit = 20; offset = 0; results = ... etag = b38bb16e6d445c247e1edb3b5decde4f3caa1b2d; status = Ok;
5. Чтобы сделать что-то значимое с выводом, мы проанализируем его и преобразуем в структуру, чтобы мы могли использовать данные. Давайте определим класс структуры.
Поэтому создайте файл с именем Character.swift. Добавьте поля, которые мы будем анализировать из ответа. Файл должен напоминать содержимое ниже:
import Foundation import JSONJoy struct Character : JSONJoy { var status: String? var code: Int? var thumbnail: String? init() { } init(_ decoder: JSONDecoder) { status = decoder["status"].string code = decoder["code"].integer if let arr = decoder["data"]["results"].array { let path = arr[0]["thumbnail"]["path"].string let fileExtension = arr[0]["thumbnail"]["extension"].string thumbnail = "\(path!).\(fileExtension!)" } } }
Мы используем JSONJoy-Swift для анализа ответа. Код принимает ответ в соответствии с документацией и присваивает его полям в структуре.
Теперь в нашем методе загрузки нам нужно проанализировать ответ в структуре символов.
@IBAction func download(sender: AnyObject) { let name = "Ant-Man" let url = "http://gateway.marvel.com:80/v1/public/characters" var request = HTTPTask() request.responseSerializer = JSONResponseSerializer() let publicKey = "YOUR PUBLIC KEY" let privateKey = "YOUR PRIVATE KEY" let ts = NSDate().timeIntervalSince1970.description let hash = "\(ts)\(privateKey)\(publicKey)".md5() request.GET(url, parameters: ["nameStartsWith": name, "apikey": publicKey, "ts" : ts, "hash": hash], success: { (response: HTTPResponse) -> Void in if (response.responseObject != nil) { let character = Character(JSONDecoder(response.responseObject!)) } },{(error: NSError, response: HTTPResponse?) -> Void in println("got an error: \(error)") }) }
Мы добавили responseSerializer, чтобы он был JSONResponseSerializer. И мы преобразовали ответ в структуру символов.
6. Последняя часть головоломки — загрузить миниатюру и назначить ее для UIImageView. Для этого мы будем использовать SwiftHTTP и скачать изображение, используя это. Мы добавим метод, который принимает структуру символов, загружает миниатюру и назначает ее для UIImageView. Я не буду вдаваться в подробности этого метода, так как в действительности речь идет о том, как использовать SwiftHTTP, а не о том, как использовать API Marvel, о котором пойдет речь в этой статье.
func downloadCharacter(character: Character) { var request = HTTPTask() let downloadTask = request.download(character.thumbnail!, parameters: nil, progress: {(complete: Double) in println("percent complete: \(complete)") }, success: {(response: HTTPResponse) in println("download finished!") if response.responseObject != nil { let data = NSData(contentsOfURL: response.responseObject! as NSURL) dispatch_async(dispatch_get_main_queue()) { self.imageView.image = UIImage(data: data!) } } } ,failure: {(error: NSError, response: HTTPResponse?) in println("failure") }) }
Обратите внимание, что назначение imageView происходит в основном потоке. Это правильный способ обновления любого объекта просмотра.
7. Так что, если мы соберем все вместе сейчас. Мы можем вызвать функцию downloadCharacter из нашей функции загрузки.
@IBAction func download(sender: AnyObject) { let name = "Ant-Man" let url = "http://gateway.marvel.com:80/v1/public/characters" var request = HTTPTask() request.responseSerializer = JSONResponseSerializer() let publicKey = "YOUR PUBLIC KEY" let privateKey = "YOUR PRIVATE KEY" let ts = NSDate().timeIntervalSince1970.description let hash = "\(ts)\(privateKey)\(publicKey)".md5() request.GET(url, parameters: ["nameStartsWith": name, "apikey": publicKey, "ts" : ts, "hash": hash], success: { (response: HTTPResponse) -> Void in if (response.responseObject != nil) { let character = Character(JSONDecoder(response.responseObject!)) self.downloadCharacter(character) } },{(error: NSError, response: HTTPResponse?) -> Void in println("got an error: \(error)") }) }
Мы должны иметь возможность запустить наше приложение, нажать кнопку «Загрузить» и увидеть Ant-Man во всей его красе.
Ну это все. Надеюсь, вы видели достаточно, чтобы начать использовать API Marvel в приложении Swift. Удачи в создании собственного приложения, использующего замечательную вселенную Marvel.
Вот несколько ссылок: