Наступил октябрь, и пока люди во всем мире празднуют Октоберфест, у разработчиков целый месяц Хактоберфест! 🎃

Что такое Хактоберфест?

Hacktoberfest - это месячный праздник программного обеспечения с открытым исходным кодом, которым управляет DigitalOcean в партнерстве с GitHub и Twilio.

● Хактоберфест открыт для всех в нашем глобальном сообществе!

● В общедоступные репозитории GitHub необходимо отправить пять качественных запросов на вытягивание.

● Вы можете зарегистрироваться в любое время с 1 по 31 октября. (Официальный сайт Хактоберфеста)

Самое лучшее в Хактоберфесте - это то, что первые 50 000 разработчиков, которые отправят 5 запросов на включение, получат футболку и стикеры! 🤩

Как вы могли заметить, я начал делать свои первые шаги в разработке ПО с открытым исходным кодом, поэтому Hacktoberfest - это фантастическая возможность двигаться дальше и внести еще один вклад в течение этого месяца!

Кроме того, я изучаю Swift с прошлого месяца, поэтому я подумал, что было бы здорово попрактиковаться в имеющихся у меня навыках и узнать что-то новое.

Вот почему я начал искать проблемы в проектах iOS на GitHub. Через некоторое время я нашел несколько проектов, над которыми нужно работать. Самый интересный назывался DiveLane:



DiveLane - Универсальная платежная система Ethereum

Особенности:
Позвольте вам освободиться от жестких решений, таких как (Laptop + Chrome + MetaMask + Private key) привязка.
Совместное использование закрытого ключа не требуется! Храните его в одном месте, подписывайте где угодно!
Полная поддержка EIP-681 (схема URI). Еще больше:
Подписывайте транзакции и вызывать произвольные методы контракта через глубокие ссылки (из DiveLane documentatio n).

Как я понял, проект создавался на хакатоне и сейчас находится в стадии активной разработки.

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

Моей задачей было заменить все методы URLSession на методы Alamofire в проекте. Из моего первоначального исследования я обнаружил, что было 4 использования URLSession.

До этого PR я не занимался сетью на Swift, поэтому мне пришлось узнать о URLSession, Alamofire и почему я должен использовать Alamofire вместо собственного URLSession API.

URLSession

Класс URLSession и связанные классы предоставляют API для загрузки контента.
С помощью URLSession API ваше приложение создает один или несколько сеансов, каждый из которых координирует группу связанных задач передачи данных. Например, если вы создаете веб-браузер, ваше приложение может создать один сеанс для каждой вкладки или окна или один сеанс для интерактивного использования, а другой - для фоновых загрузок. В рамках каждого сеанса ваше приложение добавляет серию задач, каждая из которых представляет собой запрос на определенный URL-адрес (при необходимости следуя HTTP-перенаправлениям).
(Документация для разработчиков Apple)

Таким образом, этот API позволяет разработчику загружать и скачивать контент через запросы HTTP / HTTPS.

Аламофайр

Alamofire - сетевая библиотека HTTP, созданная на основе URLSession от Apple. Это просто элегантный способ сетевой реализации в Swift.

Элегантность Alamofire объясняется тем, что он был написан с нуля на Swift и не ничего унаследовал от своего аналога Objective-C, AFNetworking. (Учебное пособие по Alamofire: начало работы)

Почему я должен использовать Alamofire вместо собственного URLSession API?

Alamofire делает код более чистым, поскольку устраняет необходимость писать шаблонный код.

А теперь пора практиковаться!

После того, как я разветвился и настроил свой локальный репозиторий, первое, что я попробовал, - это создать приложение в Xcode. Однако сборка не удалась, но сообщение об ошибке было довольно очевидным и сообщило мне, что зависимости не установлены. Это была первая проблема, с которой я столкнулся. Тем не менее решение было довольно простым. В проекте используется CocoaPods в качестве диспетчера зависимостей, поэтому я установил зависимости, запустив:

pod install

После того, как зависимости были установлены, я смог собрать проект.

Во-первых, мне пришлось установить в проект Alamofire. Я добавил зависимость Alamofire в Podfile (файл со всеми зависимостями), добавив эту строку:

pod 'Alamofire', '~> 4.7'

Затем я побежал:

pod install

Alamofire успешно установлен в проект ✅

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

Вот пример внесенного мной изменения. Вот фрагмент кода, использующий URLSession:

let task = URLSession.shared.dataTask(with: url) { (data, _, error) in
if let data = data {
do {
    let jsonSerialized = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any]
    if let json = jsonSerialized {
      if let conversionRate = json["USD"] as? Double {
        DispatchQueue.main.async {
           self.conversionRates[tokenName] = conversionRate
           completion(conversionRate)
        }
       } else {
          print("Can't convert to Double")
          DispatchQueue.main.async {
               completion(0)
          }
       }
}
} catch let error as NSError {
          print(error.localizedDescription)
          DispatchQueue.main.async {
          completion(0)
  }
}
} else if let error = error {
       print(error.localizedDescription)
       DispatchQueue.main.async {
       completion(0)
  }
}
}
task.resume()

И я заменил API URLSession библиотекой Alamofire:

Alamofire.request(url)
     .responseJSON { response in
           guard response.result.isSuccess else {
                print(response.result.error!.localizedDescription)
                DispatchQueue.main.async {
                     completion(0)
                }
                return
           }
           guard let value = response.result.value as? [String: Any],
           let conversionRate = value["USD"] as? Double else {
                print("Can't convert to Double")
                DispatchQueue.main.async {
                        completion(0)
                }
                return
            }
            self.conversionRates[tokenName] = conversionRate
            completion(conversionRate)
}

Намного лучше, не правда ли? 🤩

Я проделал аналогичную работу в других классах.

Затем я проверил, что приложение работает таким же образом, и это было непросто, так как в проекте не было какого-то «CONTRIBUTING.md», поэтому мне пришлось самостоятельно разобраться, как работает приложение. Понадобилось некоторое время, чтобы понять, как это работает, но это был хороший опыт, так как я стал лучше разбираться в архитектуре проекта iOS и коде Swift.

Собственно, я тоже открыл проблему в проекте, где попросил сопровождающих добавить инструкции для участников.

Наконец, я открыл свой Pull Request, и он был объединен с проектом! 🎉

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

  • изучил CocoaPods
  • выучил Alamofire
  • изучил URLSession
  • понятный код, написанный другими разработчиками
  • общался с создателями
  • успешно участвовал в проекте