Советы по улучшению вашей работы с 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
}
}
Довольно круто, правда?
Заключение
Несколько советов из моего опыта. Надеюсь, они помогут вам работать быстрее и сделать вашу работу интереснее.