Всем привет, был немного в разъездах. Возвращаюсь с очередным отчётом:
Закончил изучение Проекта 9🎆
Почему этот набор уроков называется Проектом я не понял. По итогу мы не сделали приложение, поэтому показывать нечего🗿
Но главное, что я постиг азы навигации. В моём приложении они понадобятся, поэтому я рад этому вдвойне!
На этот раз я пропущу челендж - хочу поскорее приступить к следующему разделу, который посвящён
Раздел, который имет самое большое значение в моём проекте по технической составляющей (так я это вижу на данный момент, возможно при реализации это окажется не так).
Кстати, это уже почти экватор! Отпразнуем лайком?🥳
Закончил изучение Проекта 9
Почему этот набор уроков называется Проектом я не понял. По итогу мы не сделали приложение, поэтому показывать нечего
Но главное, что я постиг азы навигации. В моём приложении они понадобятся, поэтому я рад этому вдвойне!
На этот раз я пропущу челендж - хочу поскорее приступить к следующему разделу, который посвящён
Data
.Раздел, который имет самое большое значение в моём проекте по технической составляющей (так я это вижу на данный момент, возможно при реализации это окажется не так).
Кстати, это уже почти экватор! Отпразнуем лайком?
Please open Telegram to view this post
VIEW IN TELEGRAM
🎉2👍1 1
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2 1
Приветствую 👋
Сегодня посмотрел видео (оно входит в 100 дневный курс) https://www.youtube.com/watch?v=U1gP4EcT_wQ
Формат очень интересный, на примере “Зведные Войны” рассказываются определенные аспекты программирования, в частности на Swift👩💻
На скриншотах приведены основные мысли.
Если вдруг не хватает уровня английского, то у Яндекса есть технология синхронного перевода видео. Иногда сам ей пользуюсь, работает классно!
Сегодня посмотрел видео (оно входит в 100 дневный курс) https://www.youtube.com/watch?v=U1gP4EcT_wQ
Формат очень интересный, на примере “Зведные Войны” рассказываются определенные аспекты программирования, в частности на Swift
На скриншотах приведены основные мысли.
Если вдруг не хватает уровня английского, то у Яндекса есть технология синхронного перевода видео. Иногда сам ей пользуюсь, работает классно!
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
В видео приводится такой фрагмент. Он показывает, что поведение этого кода сложно описать без знания чем является
Как хорошо, что у нас есть IDE🤩
Target
, классом или структурой.Как хорошо, что у нас есть IDE
Please open Telegram to view this post
VIEW IN TELEGRAM
Просмотра видео, конечно, недостаточно. Нужно скорее изучать следующие темы!
Проект 10 (1/4)
Оставил у меня смешанные чувства: огорчение и восторг.
Я был полон ожидания, что в разделе Focus on data мы начнём с разбора фреймворка базы данных - Core Data. Эта тема действительна интересна для меня, возможно как для backend разработчика. Но мы начали с
🟢 http запросов.
В сравнение с Java/Kotlin - просто вау! Встроенные механизмы, которые для базовых кейсов не требуют почти никаких усилий. Когда разработчики постарались🙂
Насколько мне удалось нагуглить, для любителей перекладывать байтики, инструменты в виде IntputStream/OutputStream имеются😎
🟢 Асинхронная загрузка изображений. Тут дело сложнее чем с обычными картинками, т.к. SwiftUI заранее не знает, какими атрибутами обладает загружаемая картинка. Но мы можем подсказать.
🟢 Disabling Forms. Это совсем не то, что можно ожидать в разделе Focus on Data 🫠
В форме можно указать boolean выражение на секции, которое заблокирует или разрешит взаимодействие с этой секцией.
#hackingwithswift
Проект 10 (1/4)
Оставил у меня смешанные чувства: огорчение и восторг.
Я был полон ожидания, что в разделе Focus on data мы начнём с разбора фреймворка базы данных - Core Data. Эта тема действительна интересна для меня, возможно как для backend разработчика. Но мы начали с
let url = URL(string: "https://itunes.apple.com/search?term=taylor+swift&entity=song")
let (data, _) = try await URLSession.shared.data(from: url)
В сравнение с Java/Kotlin - просто вау! Встроенные механизмы, которые для базовых кейсов не требуют почти никаких усилий. Когда разработчики постарались
Насколько мне удалось нагуглить, для любителей перекладывать байтики, инструменты в виде IntputStream/OutputStream имеются
Section {
Button("Create account") {
print("Creating account…")
}
}
.disabled(username.isEmpty || email.isEmpty)
В форме можно указать boolean выражение на секции, которое заблокирует или разрешит взаимодействие с этой секцией.
#hackingwithswift
Please open Telegram to view this post
VIEW IN TELEGRAM
Чем дальше, тем больше хочу погрузиться в мир мобильной разработки! 💪
Please open Telegram to view this post
VIEW IN TELEGRAM
🆒2
Антиреклама Xcode
Ожидается, что на симуляторе и превью будет одинаковый контент. Куда пропали остальные секции Пол тоже не знает…😄
Ожидается, что на симуляторе и превью будет одинаковый контент. Куда пропали остальные секции Пол тоже не знает…
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1😱1 1
Недавно я хвалил разработчиков за URLSession, но сегодня случай другой.
Допустим, нам нужно создать JSON, но при этом заменить имена полей на кастомные. В
Это выглядит громоздко, и если мы посмотрим на class + Observable, то поля с подчёркиванием ещё больше усложняют восприятие
В
Допустим, нам нужно создать JSON, но при этом заменить имена полей на кастомные. В
Swift
для этого используется специальный enum CodingKeys: String, CodingKey
:
struct Landmark: Codable {
var name: String
var foundingYear: Int
var location: Coordinate
var vantagePoints: [Coordinate]
enum CodingKeys: String, CodingKey {
case name = "title"
case foundingYear = "founding_date"
case location
case vantagePoints
}
}
Это выглядит громоздко, и если мы посмотрим на class + Observable, то поля с подчёркиванием ещё больше усложняют восприятие
@Observable
class User: Codable {
enum CodingKeys: String, CodingKey {
case _name = "name"
}
var name = "Taylor"
}
В
Kotlin
это делается существенно лаконичнее:
import com.fasterxml.jackson.annotation.JsonProperty
data class Landmark(
@JsonProperty("title") val name: String,
@JsonProperty("founding_date") val foundingYear: Int,
val location: Coordinate,
val vantagePoints: List<Coordinate>
)
@JsonProperty
является аннотацией, которая доступна в рантайм, являющаяся по сути мета информацией к типу Landmark. Библиотека fasterxml использует её при сериализации.👍1
Для
Swift
есть решение похожее на fasterxml
- https://github.com/GottaGetSwifty/CodableWrappers
@CustomCodable @SnakeCase
struct User: Codable {
let firstName: String
let lastName: String
@SecondsSince1970DateCoding
var joinDate: Date
@CustomCodingKey("data")
var imageData: Data
}
👍1
Проект 10
Закончен.
Повторюсь, мне он показался странным. Не то, что я ожидал увидеть.
Я так и не понял зачем был урок про haptic effects - тактильные ощущения, которые создаются с помощью вибрации телефона, причем только на телефоне эта функциональность доступна. В проекте мы это не применяли.
Проект был про приложение для заказа кексиков.
По функционалу состоит из формы и её валидации, асинхронной загрузки картинки, нескольких экранов и отправки http запросов с json на сервер.
Едем дальше🚗
Закончен.
Повторюсь, мне он показался странным. Не то, что я ожидал увидеть.
Я так и не понял зачем был урок про haptic effects - тактильные ощущения, которые создаются с помощью вибрации телефона, причем только на телефоне эта функциональность доступна. В проекте мы это не применяли.
Проект был про приложение для заказа кексиков.
По функционалу состоит из формы и её валидации, асинхронной загрузки картинки, нескольких экранов и отправки http запросов с json на сервер.
Едем дальше
Please open Telegram to view this post
VIEW IN TELEGRAM
Прохожу Проект 11, и там, наконец-то, то, чего я ждал - работа с данными. Думаю, завтра завершу и напишу пост об этом.
⚡1👏1
Это, как говорится, ни в какие ворота не лезет. Я потратил ❗️ 15 минут ❗️ на поиск простой опечатки (параметр называется configurations).
Бесполезный linter…😤
Бесполезный linter…
Please open Telegram to view this post
VIEW IN TELEGRAM
😢1
А теперь вопрос к SwiftUI.
Почему нет конструктора для ClosedRange, но есть для Range? Забыли посахарить? 😄
На первый взгляд ClosedRange является подтипом Range. Но первое впечатление обманчиво, видимо нужно погружаться в теорию типов.
Фиксится через добавление id
В этом случае тип становится
Почему нет конструктора для ClosedRange, но есть для Range? Забыли посахарить? 😄
На первый взгляд ClosedRange является подтипом Range. Но первое впечатление обманчиво, видимо нужно погружаться в теорию типов.
Фиксится через добавление id
ForEach(1...maxRating, id: \.self)
В этом случае тип становится
Data
public init(_ data: Data, id: KeyPath<Data.Element, ID>, @ViewBuilder content: @escaping (Data.Element) -> Content)
🤔1
Проект 11
Этот проект оказался самым полезным, поскольку его функционал сильно пересекается с тем, что я планирую реализовать в своём приложении.
Основные темы:
🟢
🟢
🟢 SwiftData - новый механизм для персистентного хранения данных в iOS, аналогичный
🟢 Кастомные View, которые можно комбинировать и использовать в других View. Это помогает создавать переиспользуемые компоненты, улучшая читаемость и структуру кода.
🟢
Кстати, когда я пытался сделать приложение с помощью ChatGPT, он почему-то предложил использовать CoreData, и про SwiftData ничего не сказал. Хотя последнее идеально подходит для моей задачи.
hackingwithswift.com отличный курс, который уже научил меня многому.
#hackingwithswift
Этот проект оказался самым полезным, поскольку его функционал сильно пересекается с тем, что я планирую реализовать в своём приложении.
Основные темы:
@Binding
- позволяет изменять значение, переданное извне. Используем, когда нужно передать тип данных из View 1 в View 2, и при этом View 2 может модифицировать переданное значение. Это полезно для двусторонней связи между представлением и моделью.TextEditor
- многострочная версия TextField
. Подходит для ввода текста, который может “расти” в высоту или ширину в зависимости от содержимого. Очень удобен для реализации многострочных полей ввода.CoreData
, но более абстрактный и с упрощённым интерфейсом. Несмотря на скромные возможности по сравнению с CoreData, SwiftData легче в освоении и значительно проще в использовании для базовых задач. Это именно то, что мне нужно для быстрого старта.@Query
- позволяет фильтровать и сортировать данные, хранимые в SwiftData, без необходимости писать сложные запросы вручную. Это упрощает работу с данными и позволяет быстрее получить нужную информацию.Кстати, когда я пытался сделать приложение с помощью ChatGPT, он почему-то предложил использовать CoreData, и про SwiftData ничего не сказал. Хотя последнее идеально подходит для моей задачи.
hackingwithswift.com отличный курс, который уже научил меня многому.
#hackingwithswift
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥1👏1💯1
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1👏1
Попробовал посмотреть другие ресурсы для изучения Swift. Вроде выглядит неплохо - codecademy
Проходил модуль про enum: https://www.codecademy.com/courses/learn-swift-enumerations/lessons/swift-enumerations-lesson/exercises/introducing-enumerations
Вроде как сам урок бесплатный, но тест и проект (тут нужно без примеров по инструкции реализовывать функционал) уже платные.
Из полезного: увидел как делается и попробовал на практике
🟢 RawValue - можно каждому enum сопоставить какое-то значение. Тут можно и String сделать.
🟢 CaseIterable - чтобы проитерироваться по всем значениям
🟢 Ассоциированные значения - каждый enum может содержать свою переменную (наверное, несколько тоже можно)
🟢 Мутирующие методы
Попробую ещё несколько модулей, расскажу по мере прохождения. Но пока курс hackingwithswift в приоритете, и я планирую пройти его до конца.
А кто-то уже пользовался codecademy, можете поделиться своим опытом?
Проходил модуль про enum: https://www.codecademy.com/courses/learn-swift-enumerations/lessons/swift-enumerations-lesson/exercises/introducing-enumerations
Вроде как сам урок бесплатный, но тест и проект (тут нужно без примеров по инструкции реализовывать функционал) уже платные.
Из полезного: увидел как делается и попробовал на практике
enum Team: Int {
case alpha = 1
case bravo
case charlie
case delta
}
print(Team.delta.rawValue) // вывод: 4
let team = Team(rawValue: 3) // создаст .charlie
enum Season: CaseIterable {
case winter
case spring
case summer
case fall
}
// потом можно так
for season in Season.allCases {
print(season)
}
enum Dessert {
case cake(flavor: String)
case vanillaIceCream(scoops: Int)
case brownie
}
let tonightsSpecial = Dessert.vanillaIceCream(scoops: 4)
switch tonightsSpecial {
case let .cake(cakeFlavor):
print("Time for \(cakeFlavor) cake")
case let .vanillaIceCream(scoopCount):
print("\(scoopCount) scoops of vanilla ice cream")
case .brownie:
print("Decadent goodness")
}
// Вывод: 4 scoops of vanilla ice cream
enum Season {
case winter, spring, summer, fall
mutating func changeSeason() {
switch self {
case .winter:
self = .spring
case .spring:
self = .summer
case .summer:
self = .fall
case .fall:
self = .winter
}
}
}
Попробую ещё несколько модулей, расскажу по мере прохождения. Но пока курс hackingwithswift в приоритете, и я планирую пройти его до конца.
А кто-то уже пользовался codecademy, можете поделиться своим опытом?
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥1🤔1👀1
Проект 12: дни 57-59
Это был технический проект направленный на чуть большее понимание деталей работы с SwiftData.
🟢 Чтобы SwiftData заработал, достаточно:
1. Создать модель в виде класса и добавить
2. Заинжектить
3. Во View получить доступ к
Всё действительно просто😍
🟢 Для
🟢 Показана фильтрация в 😮
🟢
🟢 🔍
Забавно, что у SwiftData есть свой значок📦
#hackingwithswift
Это был технический проект направленный на чуть большее понимание деталей работы с SwiftData.
1. Создать модель в виде класса и добавить
@Model
макрос.2. Заинжектить
modelContainer
для этого класса.3. Во View получить доступ к
modelContext
через @Environment(\.modelContext) var modelContext
Всё действительно просто
#Preview
можно сделать свой modelContainer
, который будет храниться в памяти. Выглядит это немного громоздко, но явно есть инструменты позволяющие сократить код. Удивлюсь если их нет, preview весьма полезный инструмент, и используется часто.@Query
- как же ужасно это выглядит! Особенно, если развернуть макрос. Почему там нельзя использовать обычную лямбду/замыкание? SwiftData
умеет неявно делать связи между моделями. Мы можем просто объявить новое поле, тип которого другая модель (или даже список/массив). Каскадное удаление также присутствует, но тут уже нужно добавить макрос как в этом примере: @Relationship(deleteRule: .cascade) var jobs = [Job]()
CloudKit
- пока загадочный для меня фреймворх для хранения там данных приложения. Классно, что SwiftData
может с ним синхронизироваться, позволяя также синхронизировать данные между девайсами. Но, почитав документация, я понимаю, что он предназначен для публичных данных, а iCloud для приватных. Я могу сказать, что всё что на моём телефоне и связано со мной - приватное! Какой у этого реальный юзкейс ещё предстоит выяснить Забавно, что у SwiftData есть свой значок
#hackingwithswift
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1👏1
В дополнение к пункту про фильтрацию в
Посмотрите сами… этот код не является валидным
@Query
Посмотрите сами… этот код не является валидным
@Query(filter: #Predicate<User> { user in
if user.name.localizedStandardContains("R") {
if user.city == "London" {
return true
}
}
return false
}, sort: \User.name) var users: [User]