Советы по улучшению вашей работы с iOS

Некоторые советы, приведенные ниже, помогают мне работать быстрее и эффективнее.

1. Не зависеть от серверного API.

API-интерфейсы чрезвычайно важны, и мы ничего не можем сделать без API-интерфейсов. Итак, можем ли мы смотреть Youtube или Facebook, пока бэкэнд-команды зарываются носами в код?
В ближайшее время вы получите предупреждение от своего менеджера.
Или API-интерфейсы являются медленными и трудными для тестирования при их разработке. Что нам делать?

Don't depend on server API. Just depend on the schemas.

  • Спросите у бэкэнд схемы API, которые они присылают нам, когда мы звоним. Сохраните его в файл json.
  • Воспользуйтесь советом №2 или №3 для создания своей модели данных.
  • Настройте свой код при вызове API. Я обычно разделяю вызовы API на workers. Вы можете поступить по-своему.
class GetUserDetailWorker {
// (1)
    func run(completion: @escaping(User?, Error?) -> Void) {
        Alamofire.request() {
            handleResponse(response: AnyObject, completion: completion)
        }
    }

// (2)
    private func handleResponse(response: AnyObject?, completion: @escaping(User?, Error?) -> Void) {
        // parse json to your data model
        // check logic
        // ...
        // call completion
    }
}

(1): ваши контроллеры не знают, что находится внутри GetUserDetailWorker. Они реагируют на успех или неудачу со стороны работника. Итак, вы можете подделать здесь любые данные и посмотреть, как на них реагируют ваши контроллеры.

(2): здесь вы анализируете необработанный json для своей модели данных, обрабатываете логику и ответ.

А теперь сделай трюк. Добавьте функцию после вашей handleResponse функции.

func loadLocally(completion: @escaping(User?, Error?) -> Void) {
    if let filepath = Bundle.main.path(forResource: "User", ofType: "json") {
        do {
            let contents = try String(contentsOfFile: filepath)
            let data = contents.data(using: .utf8)!
            if let json = try JSONSerialization.jsonObject(with: data, options : .allowFragments) as AnyObject? {
                handleResponse(response: json, completion: completion)
                } else {
                    print("bad json")
                }
        } catch {
            completion(nil, error)
        }
    }
}

Добавьте это в начале run функции.

loadLocally(completion: completion)
return

Загружаем user.json и отправляем на контроль. Он у вас на компьютере, мы можем изменить любые данные, как захотим. Когда API будут готовы, просто удалите эти 2 строки, и все начнет работать, как по заклинанию.

Некоторые преимущества

  • Быстро. Вы звоните со своего компьютера, без задержек или в зависимости от Интернета.
  • Удобный. Вы можете изменить любые данные, какие хотите, хорошие случаи, плохие случаи и изменить свой пользовательский интерфейс по необходимости.
  • Независимый. Вы больше не зависите от прогресса сервера.

2. Создайте функцию инициализации.

Когда вы определяете struct, Swift может дать вам init функцию, вам не нужно писать ее самостоятельно. Но если пользоваться class, то нет бесплатного init. Что делать, если у вас долгий урок init, как показано ниже.

class User {
    var id: String
    var tasks: [String]
    var email: String?
    var membershipExpirationDate: Date?
    var startDate: Date?
    var cancelAtPeriodEnd: Bool?
    var balance: Int
    let phoneNumber: String?
    let currency: String
    init(id: String, tasks: [String], email: String?, membershipExpirationDate: Date?, startDate: Date?, cancelAtPeriodEnd: Bool?, balance: Int, phoneNumber: String?, currency: String) {
        self.id = id
        self.tasks = tasks
        self.email = email
        self.membershipExpirationDate = membershipExpirationDate
        self.startDate = startDate
        self.cancelAtPeriodEnd = cancelAtPeriodEnd
        self.balance = balance
        self.phoneNumber = phoneNumber
        self.currency = currency
    }
}

Вы хотите напечатать это сами? Попробуйте так.

Примечания

  • Нажмите option и перетащите, чтобы выбрать многострочность.
  • Удалите неиспользуемые слова.
  • Скопируйте имя свойства.
  • Нажмите, esc чтобы закрыть несколько курсоров.

3. Анализировать результат JSON.

Я не фанат Codable. Это действительно полезно в простых ответах, но в сложных, нет. А также отлаживать тоже сложно.

Большую часть работы я разбираю JSON вручную, не использую SwiftyJSON или аналогичными программами. Однажды я присоединился к команде со сложными ответами. Пример ниже.

{
  "Id": "b206bb24-03ab-4a25-a9c4-b26e2fd2e9f8",
  "Name": "Hexagon 21",
  "ScreenName": null,
  "Picture": "https://scontent.xx.fbcdn.net/v/t1.0-9/20245457_303012200102286_1324449236613079430_n.jpg?_nc_cat=104&_nc_oc=AQmRtf3n0fmK36Z8Vnzz5QFECni4m52YHbm0GbzdSEI6slVpgf59oGBHZCeOBv3yzGc&_nc_ht=scontent.xx&oh=24ebc12ea4244757e584f7f438e06e44&oe=5E613D7C",
  "ExternalId": "575475522634796",
  "FacebookUserId": null,
  "Account": null,
  "Type": 1,
  "Subtype": "FacebookGroup",
  "IsDefault": false,
  "Credential": null,
  "AssociatedSource": null,
  "PublishMessageProfiles": null,
  "ProfileSubscribeNotifications": null,
  "Selected": false,
  "HasAppInstalled": null,
  "IsWebHookSubscribed": false,
  "IsTwitterWebHookSubscribed": null
}

Теперь сделать класс из них – скучная работа.

  • Используйте это: https://app.quicktype.io/ .
  • Изучите параметры на правой панели, чтобы увидеть, как они меняются.
    И вот результат:
class User {
    var id: String?
    var name: String?
    var screenName: NSNull?
    var picture: String?
    var externalID: String?
    var facebookUserID: NSNull?
    var account: NSNull?
    var type: Int?
    var subtype: String?
    var isDefault: Bool?
    var credential: NSNull?
    var associatedSource: NSNull?
    var publishMessageProfiles: NSNull?
    var profileSubscribeNotifications: NSNull?
    var selected: Bool?
    var hasAppInstalled: NSNull?
    var isWebHookSubscribed: Bool?
    var isTwitterWebHookSubscribed: NSNull?

    init(id: String?, name: String?, screenName: NSNull?, picture: String?, externalID: String?, facebookUserID: NSNull?, account: NSNull?, type: Int?, subtype: String?, isDefault: Bool?, credential: NSNull?, associatedSource: NSNull?, publishMessageProfiles: NSNull?, profileSubscribeNotifications: NSNull?, selected: Bool?, hasAppInstalled: NSNull?, isWebHookSubscribed: Bool?, isTwitterWebHookSubscribed: NSNull?) {
        self.id = id
        self.name = name
        self.screenName = screenName
        self.picture = picture
        self.externalID = externalID
        self.facebookUserID = facebookUserID
        self.account = account
        self.type = type
        self.subtype = subtype
        self.isDefault = isDefault
        self.credential = credential
        self.associatedSource = associatedSource
        self.publishMessageProfiles = publishMessageProfiles
        self.profileSubscribeNotifications = profileSubscribeNotifications
        self.selected = selected
        self.hasAppInstalled = hasAppInstalled
        self.isWebHookSubscribed = isWebHookSubscribed
        self.isTwitterWebHookSubscribed = isTwitterWebHookSubscribed
    }
}

Довольно круто, правда?

Заключение

Несколько советов из моего опыта. Надеюсь, они помогут вам работать быстрее и сделать вашу работу интереснее.

Ответить