В детстве я постоянно поглощал 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.
Вот несколько ссылок:

