Всё же работа со строками в Swift устроена сложнее, чем в Kotlin.
В Swift индексы представлены специальными типами (String.Index), поэтому нельзя просто обратиться к символу по числовому индексу, как в Kotlin (string[index]). Вместо этого используется index(_:offsetBy:):
Говорят, что это делает работу со строками в Swift более безопасной, особенно при обработке многобайтовых символов, таких как emoji. Компромиссное решение, которое вызывает у меня смешанные ощущения.
В Swift индексы представлены специальными типами (String.Index), поэтому нельзя просто обратиться к символу по числовому индексу, как в Kotlin (string[index]). Вместо этого используется index(_:offsetBy:):
let text = "Hello"
let index = text.index(text.startIndex, offsetBy: 1)
print(text[index]) // "e"
val text = "Hello"
println(text[1]) // "e"
Говорят, что это делает работу со строками в Swift более безопасной, особенно при обработке многобайтовых символов, таких как emoji. Компромиссное решение, которое вызывает у меня смешанные ощущения.
🤔1
День 61
Снова челленж, но он является продолжением предыдущего. Нужно теперь сохранить, тот JSON что мы скачиваем, в SwiftData.
Чтобы проверить, что данные берутся из SwiftData, я добавил лишний символ в URL - РАБОТАЕТ!
Впереди нас ждет работа с картинками, а потом и с картами. Звучит интригующе🤩
#hackingwithswift
Снова челленж, но он является продолжением предыдущего. Нужно теперь сохранить, тот JSON что мы скачиваем, в SwiftData.
Чтобы проверить, что данные берутся из SwiftData, я добавил лишний символ в URL - РАБОТАЕТ!
Впереди нас ждет работа с картинками, а потом и с картами. Звучит интригующе
#hackingwithswift
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥1🆒1
Чтобы работали и SwiftData, и JSONDecoder, нужно сделать такие страшные вещи 😱
Написать кастомные encoder/decoder методы.
Написать кастомные encoder/decoder методы.
Please open Telegram to view this post
VIEW IN TELEGRAM
😱2
Проект 13 (Day 62) - состоит аж из 6 частей. Обычно проект состоит из 3. Буду его дробить на части поменьше.
🟢 Заглянули во внутренности
🟢
🟢
#hackingwithswift
State
проперти враппера. Но не настолько сильно, чтобы понять как он работает на 100%. Однако эти детали помогают понять почему этот код не работает при изменении поля через bindings:
@State private var blurAmount = 0.0 {
didSet {
print("New value is \(blurAmount)")
}
}
onChange
- позволяет подписаться на любые изменения переменной
Slider(value: $blurAmount, in: 0...20)
.onChange(of: blurAmount) { oldValue, newValue in
print("New value is \(newValue)")
}
confirmationDialog
- диалоговое окно похожее на alert
, но мне оно кажется функциональнее, т.к. оно и его кнопки находятся внизу, что позволяет быстрее и легче взаимодействовать с ним (не нужно тянуться пальцем к середине экрана, как в случае с `alert`).#hackingwithswift
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Проект 13 (Day 63)
Сегодня были 2 темы. Порой это сильно удивляет, насколько малосвязанные темы включаются в один урок.
🟢
🟠
🟠
🟠
🟠
🟢
#hackingwithswift
Сегодня были 2 темы. Порой это сильно удивляет, насколько малосвязанные темы включаются в один урок.
CoreImage
- оказывается, для представления изображений в iOS есть четыре основных типа:SwiftUI Image
- View для отображения изображений в SwiftUI.UIImage
- изображение из UIKit. Обширный функционал, поддерживает форматы PNG, SVG и другие.CGImage
- Core Graphics. По сути двумерный массив пикселей.CIImage
- Core Image. Автор называет его “рецептом для создания изображения”. Поддерживает различные фильтры, такие как pixellate
, crystallize
, sepiaTone
и другие.ContentUnavailableView
- view с иконкой, текстом и кнопкой (которые можно кастомизировать по своему усмотрению), предназначенное для отображения, когда контент недоступен.#hackingwithswift
Please open Telegram to view this post
VIEW IN TELEGRAM
Проект 13 (Day 64)
Следующий урок закончил! 2 за 1 день - достойно похвалы, пойду съем по этому случаю яблоко👩💻
Сегодня в программе:
🟢 Выбор изображения из библиотеки фото. Делается это с помощью
🟢
🟢
Следующий урок закончил! 2 за 1 день - достойно похвалы, пойду съем по этому случаю яблоко
Сегодня в программе:
PhotosPicker
. Однозначно мне пригодится!ShareLink
- конфигурируемый элемент, чтобы вызвать диалоговое окно share. Думаю все и так знают что это такое.@Environment(\.requestReview) var requestReview
- попросить пользователя оставить отзыв. Вызывается как функция requestReview()
.Please open Telegram to view this post
VIEW IN TELEGRAM
👍1🔥1
Стало интересно что такое
Это инстанс структуры
Не помню чтобы про это рассказывалось, но callAsFunction в Swift позволяет делать вызов этой функции на объекте, не указывая название этой функции.
В Kotlin тоже есть такой функционал, выглядело бы это так:
Что такое
requestReview
.Это инстанс структуры
RequestReviewAction
определенной как:
// Available when SwiftUI is imported with StoreKit
@available(iOS 16.0, visionOS 1.0, macOS 13.0, *)
@available(tvOS, unavailable)
@available(watchOS, unavailable)
@MainActor public struct RequestReviewAction {
@MainActor public func callAsFunction()
}
Не помню чтобы про это рассказывалось, но callAsFunction в Swift позволяет делать вызов этой функции на объекте, не указывая название этой функции.
В Kotlin тоже есть такой функционал, выглядело бы это так:
class RequestReviewAction {
operator fun invoke() {
println("Requesting review...")
}
}
fun main() {
val requestReview = RequestReviewAction()
requestReview()
}
Что такое
@MainActor
ещё предстоит узнать #todo👍2
Какой подход вам ближе?
Final Results
67%
callAsFunction 👩💻
33%
invoke 👩💻
0%
Оба отлично смотрятся 💪
Kotlin/Swift (iOS) Туда и Обратно
Какой подход вам ближе?
После жарких дебатов наш консилиум решил оставить 👩💻 отправлена в архив, страница с жалобами - удалена.
callAsFunction
. Петиция в Apple Please open Telegram to view this post
VIEW IN TELEGRAM
😁1
This media is not supported in your browser
VIEW IN TELEGRAM
Проект 13 (Day 65) - объединение изученного!
Сегодня добавили основные UI элементы приложения, а так же реализовали изменение интенсивности фильтра.
Дальше добавим возможность менять фильтры.
Использование и конвертация [CI, CG, UI, ]Image, как неоднократно подмечалось автором, выглядит монструозно🤯
Сегодня добавили основные UI элементы приложения, а так же реализовали изменение интенсивности фильтра.
Дальше добавим возможность менять фильтры.
Использование и конвертация [CI, CG, UI, ]Image, как неоднократно подмечалось автором, выглядит монструозно
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Какой формат интереснее?
Anonymous Poll
75%
0%
50%
50%
50%
Решать задачи на 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