Решать задачи на leetcode 👩💻 используя Swift сложнее потому, что ошибки просто нечитаемые. Конкретно эта ошибка - доступ по индексу больше чем размер массива.
Если смотреть как оптимист, то это то, что нужно, ведь приходится в голове продебажить код и найти ошибку😃
В Xcode такое встретить тоже можно 🫠
Если смотреть как оптимист, то это то, что нужно, ведь приходится в голове продебажить код и найти ошибку
В Xcode такое встретить тоже можно 🫠
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔1
Закончил Проект 13 🥳
Последним штрихом была поддержка других фильтров, и выбор активного среди них. А так же реализация share функционала.
Работа с изображениями мне нравится, и теперь это в моём ящике с инструментами! Держись фотошоп, я иду📱
Последним штрихом была поддержка других фильтров, и выбор активного среди них. А так же реализация share функционала.
Работа с изображениями мне нравится, и теперь это в моём ящике с инструментами! Держись фотошоп, я иду
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2
День 68 и это новый Проект 14. Сегодня начинаем разработку приложения-трекера мест, которые хотим посетить.
Сначала, как обычно, подготовительные уроки. Вот ключевые темы, которые пригодятся при реализации:
🟢
🟢
Можно представить его как кладовку: складывать туда удобно, но лучше не забывать наводить порядок, иначе потом найдётся куча старых ненужных файлов, как в ящике с носками.🧦
🟢 Выбор View через значение enum. Не лучший вариант с точки зрения полиморфизма, но зато просто и наглядно:
#hackingwithswift
Сначала, как обычно, подготовительные уроки. Вот ключевые темы, которые пригодятся при реализации:
Comparable
- протокол, позволяющий использовать операторы <, <=, >= и >. Полезен, если нужно сравнивать объекты собственного типа. Документация.URL.documentsDirectory
- тут приложение может сохранить свои файлы. Должно синхронизоваться с iCloud.Можно представить его как кладовку: складывать туда удобно, но лучше не забывать наводить порядок, иначе потом найдётся куча старых ненужных файлов, как в ящике с носками.
var body: some View {
switch loadingState {
case .loading:
LoadingView()
case .success:
SuccessView()
case .failed:
FailedView()
}
}
#hackingwithswift
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥1
Сколько iOS разработчиков среди нас? 🤔
Anonymous Poll
36%
iOS 👩💻
0%
Android 👩💻
36%
Другое 👩💻
27%
Не разраб (пока) 🧑🎓
Проект 14 (День 69)
1️⃣ Добрались до карт 🗺 используем MapKit.
Я приятно удивлён с какой лёгкостью они интегрируются в приложение:
Похоже, что мы ограничены только своей фантазией. С ними можно делать что угодно. Размещать SwiftUI компоненты поверх, пожалуй, самое простое из этого.
2️⃣ Touch ID & Face ID 🔒
Всё что нужно - это вежливо попросить. Остальное iOS сделает за нас.
Кстати, почему есть отдельный тип для Pointer? Я ожидал увидеть👩💻
#hackingwithswift
Я приятно удивлён с какой лёгкостью они интегрируются в приложение:
Map {
ForEach(locations) { location in
Marker(location.name, coordinate: location.coordinate)
}
}
.mapStyle(.hybrid)
Похоже, что мы ограничены только своей фантазией. С ними можно делать что угодно. Размещать SwiftUI компоненты поверх, пожалуй, самое простое из этого.
Всё что нужно - это вежливо попросить. Остальное iOS сделает за нас.
func authenticate() {
let context = LAContext()
var error: NSError?
if context.canEvaluatePolicy(
.deviceOwnerAuthenticationWithBiometrics,
error: &error
) {
let reason = "Любимые места - это маленький секрет"
context.evaluatePolicy(
.deviceOwnerAuthenticationWithBiometrics,
localizedReason: reason
) { success, authenticationError in
if success {
isUnlocked = true
}
}
}
}
Кстати, почему есть отдельный тип для Pointer? Я ожидал увидеть
*
, как в
@available(iOS 8.0, *)
open func canEvaluatePolicy(_ policy: LAPolicy, error: NSErrorPointer) -> Bool
#hackingwithswift
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Только сейчас заметил, что порядок параметров строго зафиксирован 😕
Если есть такая структура:
То такой код не работает:
После работы с Kotlin, свободный порядок именованных параметров кажется интуитивно очевидным, но это не так.
Если есть такая структура:
struct Location: Codable, Equatable, Identifiable {
let id: UUID
var name: String
var description: String
var latitude: Double
var longitude: Double
}
То такой код не работает:
Location(id: UUID(), description: "", latitude: 0, longitude: 0, name: "name")
name
должен стоять ровно между id
& description
После работы с Kotlin, свободный порядок именованных параметров кажется интуитивно очевидным, но это не так.
Please open Telegram to view this post
VIEW IN TELEGRAM
Media is too big
VIEW IN TELEGRAM
Сегодня продуктивный день! Проект 14 (День 70)
Даже не знаю про что тут рассказать. В основном использовали изученое ранее, просто собрали всё вместе.
Единственное, что в таком виде у меня не заработало, даже на физическом устройстве.
Определяем выбранную метку на карте с помощью долгого нажатия, для открытия окна редактирования:
Переделал так, заработало:
Не знаю точно, но возможно карта перехватывает жест в первом случае.
Это можно как-то затрейсить логами или отдебажить?
#hackingwithswift
Даже не знаю про что тут рассказать. В основном использовали изученое ранее, просто собрали всё вместе.
Единственное, что в таком виде у меня не заработало, даже на физическом устройстве.
Определяем выбранную метку на карте с помощью долгого нажатия, для открытия окна редактирования:
Image()
.onLongPressGesture {
selectedPlace = location
}
Переделал так, заработало:
Image()
.simultaneousGesture(LongPressGesture(minimumDuration: 1).onEnded { _ in selectedPlace = location })
Не знаю точно, но возможно карта перехватывает жест в первом случае.
Это можно как-то затрейсить логами или отдебажить?
#hackingwithswift
Ах да, была такая штука -
Чтобы вернуть из EditView новый объект, доступный в callback onSave, сделали конструктор:
Использовали
Насколько понял, этот механизм переносит замыкание из стека в heap. При этом важно не ссылаться на
@escaping
Чтобы вернуть из EditView новый объект, доступный в callback onSave, сделали конструктор:
init(location: Location, onSave: @escaping (Location) -> Void) {
self.location = location
self.onSave = onSave
_name = State(initialValue: location.name)
_description = State(initialValue: location.description)
}
Использовали
@escaping
, чтобы сказать компилятору - “будем вызывать это замыкание потом, не в этом методе”.Насколько понял, этот механизм переносит замыкание из стека в heap. При этом важно не ссылаться на
self
.🤔1
Kotlin/Swift (iOS) Туда и Обратно pinned «Сколько iOS разработчиков среди нас? 🤔»
Media is too big
VIEW IN TELEGRAM
Проект 14 (Дни 72 и 73) - финальный аккорд.
Не так уж много осталось:
🟢 Запросы к Wikipedia API, чтобы получить список мест рядом. И я проявил супер креативность 😊 - имя метки берёт title первого результата.
🟢 Сортировка списка мест, полученных из Wikipedia.
🟢 MVVM - слышал и читал про этот подход, когда делал десктопное приложение на Java. SwiftUI справляется гораздо лучше, т.к. он по-умолчанию “реактивный”.
Пока до тестов не добрался - всей прелести не увидел, но могу уже представить.
🟢 Face ID - его мы просто реализовали так же как и ранее (в подготовительном уроке). Тема раскрыта в одном из предыдущих постов.
#hackingwithswift
Не так уж много осталось:
Пока до тестов не добрался - всей прелести не увидел, но могу уже представить.
#hackingwithswift
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3
Для сравнения списков мест использовали такой подход:
Я думаю, что он неправильный, а точнее не совсем корректный.
Если взять два объекта с
В документации сказано, что так же нужно реализовывать💬 об этом, он утверждает, что реализация без
В Java это реализовано удачнее, на мой взгляд, результатом сравнения является int, который может принимать:
➡️ отрицательные значения если меньше
➡️ положительные значения если больше
➡️ ноль если равно
Реализовывать нужно всего один метод. Да, использование выглядит не так красиво (сравнение вида
struct Page: Codable, Comparable {
let pageid: Int
let title: String
let terms: [String: [String]]?
var description: String {
terms?["description"]?.first ?? "No further information"
}
static func <(lhs: Page, rhs: Page) -> Bool {
lhs.title < rhs.title
}
}
Я думаю, что он неправильный, а точнее не совсем корректный.
Если взять два объекта с
title = “a”
, в таком случае мы получим:
print(p1 < p2) // false
print(p2 < p1) // false
print(p1 == p2) // false
В документации сказано, что так же нужно реализовывать
==
, тогда этого недоразумения быть не должно. Печально, что автор об этом не говорит. Хотя я спросил у ChatGPT ==
- корректная 😄В Java это реализовано удачнее, на мой взгляд, результатом сравнения является int, который может принимать:
Реализовывать нужно всего один метод. Да, использование выглядит не так красиво (сравнение вида
a.compareTo(b) >= 0
, но Kotlin это исправляет и позволяет писать a >= b
.Please open Telegram to view this post
VIEW IN TELEGRAM
🤔1
Вот, кстати, выдержка из документации
https://developer.apple.com/documentation/swift/comparable
https://developer.apple.com/documentation/swift/comparable
👨💻1
Всем привет! Закончил Проект 15 (дни 74, 75, 76)
Очень полезная тема, но, как мне кажется, для меня ещё не самая актуальная - доступность (accessibility).
Я верю, что сначала приложение должно быть хоть в какой-то рабочей форме, но при этом написано с учётом идеи, позволяющей легко добавить доступность в будущем.
Для меня это напоминает логирование: когда разрабатываешь приложение, важно думать о traceability (особенно в распределенной системе), но по-настоящему ощущаешь полноту логов, только когда начинаешь их анализировать в тестовой среде или при отладке. То же самое с доступностью - пока не попробуешь это на устройстве, сложно оценить, что действительно нужно улучшить.
#hackingwithswift
Очень полезная тема, но, как мне кажется, для меня ещё не самая актуальная - доступность (accessibility).
Я верю, что сначала приложение должно быть хоть в какой-то рабочей форме, но при этом написано с учётом идеи, позволяющей легко добавить доступность в будущем.
Для меня это напоминает логирование: когда разрабатываешь приложение, важно думать о traceability (особенно в распределенной системе), но по-настоящему ощущаешь полноту логов, только когда начинаешь их анализировать в тестовой среде или при отладке. То же самое с доступностью - пока не попробуешь это на устройстве, сложно оценить, что действительно нужно улучшить.
#hackingwithswift
👍2
Тест на этот раз был очень хороший! Вопросы довольно таки хорошо раскрывают тему 💪
Делаю челлендж по дням 77 и 78
Пришлось сделать небольшой перерыв, но я вернулся😉
Пока испытываю трудности с организацией вьюх при нажатии на плюсик - учусь работать с асинхронными данными корректно
PhotosPicker долго загружает фото. Сейчас🤯
Размышляю как это декомпозировать.
Завтра планирую сделать рабочую версию, поэтому буду писать больше🧑💻
Пришлось сделать небольшой перерыв, но я вернулся
Пока испытываю трудности с организацией вьюх при нажатии на плюсик - учусь работать с асинхронными данными корректно
PhotosPicker долго загружает фото. Сейчас
ContentView
перегружен функционалом, и вывод списка, и добавление новой записи, и выбор фото… Размышляю как это декомпозировать.
Завтра планирую сделать рабочую версию, поэтому буду писать больше
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
От этого начинает уже иногда глаз дёргаться.
Проблема
Если у меня в определении sheet есть ошибка, то я вижу
Как решаю сейчас
В какой-то момент я понял, что с тулбаром всё в порядке. А как решение можно его закомментить и смотреть реальную ошибку.
Как это должно правильно решаться?
Подскажите кто знает, пожалуйста, я трачу реально много времени на это. Переместить тулбар вниз/наружу не получилось, т.к. он привязан к List, который находится внутри NavigationStack. Возможно стоит
Проблема
Если у меня в определении sheet есть ошибка, то я вижу
Ambiguous use of ‘toolbar(content:)’
Как решаю сейчас
В какой-то момент я понял, что с тулбаром всё в порядке. А как решение можно его закомментить и смотреть реальную ошибку.
Как это должно правильно решаться?
Подскажите кто знает, пожалуйста, я трачу реально много времени на это. Переместить тулбар вниз/наружу не получилось, т.к. он привязан к List, который находится внутри NavigationStack. Возможно стоит
sheet
на один уровень с toolbar
перенести?