Современная iOS-разработка — это не только умение писать код, но и способность быстро находить решения, генерировать идеи и автоматизировать рутину. С помощью правильно составленных промтов для нейросетей (например, ChatGPT или GitHub Copilot) можно сократить время на поиск багов, написание шаблонного кода и даже архитектурное планирование. В этой подборке — 10 проверенных мной на практике промтов, которые помогут вам в работе с SwiftUI, UIKit, Core Data и Combine. Каждый промт сопровождается реальным примером и кодом.
1. Генерация SwiftUI-вью с кастомным модификатором
Промт: «Напиши SwiftUI-вью для отображения карточки товара с изображением, названием и ценой. Добавь кастомный модификатор для тени и скругления углов. Используй iOS 16+.»
Пример использования: Вы работаете над приложением интернет-магазина и хотите быстро создать переиспользуемый компонент. Нейросеть вернёт код с ViewBuilder и модификатором cardStyle.
struct ProductCardView: View {
let imageName: String
let title: String
let price: Double
var body: some View {
VStack(alignment: .leading) {
Image(systemName: imageName)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(height: 150)
.cornerRadius(12)
Text(title)
.font(.headline)
Text("\(price, specifier: "%.2f") ₽")
.font(.subheadline)
.foregroundColor(.secondary)
}
.padding()
.cardStyle()
}
}
extension View {
func cardStyle() -> some View {
self
.background(Color.white)
.cornerRadius(16)
.shadow(color: .gray.opacity(0.3), radius: 8, x: 0, y: 4)
}
}
Совет: Уточняйте версию iOS, чтобы избежать deprecated API.
2. Оптимизация UIKit-коллекции с diffable data source
Промт: «Создай UICollectionView с compositional layout и diffable data source для отображения списка новостей. Каждая ячейка содержит заголовок, дату и краткое описание. Используй Swift.»
Пример использования: Вы переписываете старый проект с UICollectionViewDataSource на современный подход. Промт генерирует класс NewsCollectionViewController с регистрацией ячеек и снапшотом.
class NewsCollectionViewController: UICollectionViewController {
typealias DataSource = UICollectionViewDiffableDataSource<Section, NewsItem>
private var dataSource: DataSource!
override func viewDidLoad() {
super.viewDidLoad()
configureLayout()
configureDataSource()
applySnapshot()
}
private func configureLayout() {
// … compositional layout с NSCollectionLayoutSection
}
private func configureDataSource() {
let cellRegistration = UICollectionView.CellRegistration<NewsCell, NewsItem> { cell, indexPath, item in
cell.titleLabel.text = item.title
cell.dateLabel.text = item.date
cell.descriptionLabel.text = item.description
}
dataSource = DataSource(collectionView: collectionView) { collectionView, indexPath, item in
return collectionView.dequeueConfiguredReusableCell(using: cellRegistration, for: indexPath, item: item)
}
}
}
Почему это работает: Diffable data source упрощает обновление данных и предотвращает краши при асинхронной загрузке.
3. Настройка Core Data Stack с миграциями
Промт: «Напиши на Swift класс CoreDataStack с поддержкой легковесной миграции (lightweight migration) и фонового контекста для записи. Используй NSPersistentContainer.»
Пример использования: В проекте, где модель данных меняется с каждой версией, автоматическая миграция спасает от ручного SQLite-ада. Промт возвращает синглтон с viewContext и backgroundContext.
class CoreDataStack {
static let shared = CoreDataStack()
private let container: NSPersistentContainer
var viewContext: NSManagedObjectContext {
container.viewContext
}
private init() {
container = NSPersistentContainer(name: "Model")
let description = container.persistentStoreDescriptions.first
description?.shouldMigrateStoreAutomatically = true
description?.shouldInferMappingModelAutomatically = true
container.loadPersistentStores { _, error in
if let error = error { fatalError("Core Data error: \(error)") }
}
}
func saveContext() {
if viewContext.hasChanges { try? viewContext.save() }
}
}
Важно: Легковесная миграция работает только для добавления/удаления атрибутов или сущностей, но не для переименования.
4. Асинхронная загрузка изображений с Combine
Промт: «Напиши на Swift с использованием Combine загрузчик изображений с кэшированием в NSCache. Подписка должна отменяться при деините ячейки.»
Пример использования: Для UICollectionView или UITableView, где ячейки переиспользуются, критично отменять загрузку при скролле. Промт генерирует ImageLoader с PassthroughSubject.
class ImageLoader {
static let shared = ImageLoader()
private let cache = NSCache<NSString, UIImage>()
private let session = URLSession.shared
func loadImage(from url: URL) -> AnyPublisher<UIImage?, Never> {
if let cached = cache.object(forKey: url.absoluteString as NSString) {
return Just(cached).eraseToAnyPublisher()
}
return session.dataTaskPublisher(for: url)
.map { data, _ in UIImage(data: data) }
.catch { _ in Just(nil) }
.handleEvents(receiveOutput: { [weak self] image in
guard let self = self, let image = image else { return }
self.cache.setObject(image, forKey: url.absoluteString as NSString)
})
.receive(on: DispatchQueue.main)
.eraseToAnyPublisher()
}
}
Совет: Для сложных сценариев добавьте Cancellable в prepareForReuse.
5. Рефакторинг legacy-кода с UIKit на SwiftUI
Промт: «Преобразуй этот UIViewController с UITableView на SwiftUI-список. Сохрани ту же логику делегата и источника данных.»
Пример использования: Вы постепенно мигрируете приложение на SwiftUI. Нейросеть анализирует ваш код и предлагает эквивалентную List с ForEach и onDelete.
struct TodoListView: View {
@State private var items = ["Купить молоко", "Позвонить клиенту"]
var body: some View {
List {
ForEach(items, id: \.self) { item in
Text(item)
}
.onDelete(perform: deleteItems)
}
.navigationTitle("Список дел")
}
private func deleteItems(at offsets: IndexSet) {
items.remove(atOffsets: offsets)
}
}
Результат: Код становится декларативным и проще для тестирования.
6. Обработка ошибок в Combine pipeline
Промт: «Добавь обработку ошибок в Combine pipeline для сетевого запроса: при таймауте показывать алерт, при ошибке парсинга — логировать.»
Пример использования: В приложении погоды нужно корректно обрабатывать сбои сети. Промт создаёт цепочку с catch, timeout и sink.
let publisher = URLSession.shared.dataTaskPublisher(for: url)
.timeout(10, scheduler: DispatchQueue.main)
.map(\.data)
.decode(type: WeatherResponse.self, decoder: JSONDecoder())
.catch { error -> AnyPublisher<WeatherResponse, Never> in
if error is URLError {
// показать алерт
} else {
print("Parsing error: \(error)")
}
return Just(WeatherResponse.empty).eraseToAnyPublisher()
}
.sink { response in
// обновить UI
}
Совет: Используйте .replaceError(with:) для простых fallback-значений.
7. Кастомный анимационный переход в UIKit
Промт: «Создай UIViewControllerAnimatedTransitioning для кастомного перехода с масштабированием и поворотом. Анимация длится 0.5 секунды.»
Пример использования: Для презентации модального окна с эффектом «карточка переворачивается». Промт возвращает класс FlipTransition.
class FlipTransition: NSObject, UIViewControllerAnimatedTransitioning {
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return 0.5
}
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
guard let toView = transitionContext.view(forKey: .to) else { return }
let container = transitionContext.containerView
container.addSubview(toView)
toView.alpha = 0
toView.transform = CGAffineTransform(scaleX: 0.1, y: 0.1).rotated(by: .pi)
UIView.animate(withDuration: 0.5, animations: {
toView.alpha = 1
toView.transform = .identity
}) { finished in
transitionContext.completeTransition(finished)
}
}
}
Итог: Плавный переход без сторонних библиотек.
8. Тестирование Core Data с in-memory store
Промт: «Напиши unit-тест для Core Data сущности User с использованием in-memory persistent store. Проверь создание и сохранение.»
Пример использования: В тестах важно не засорять реальную базу. Промт генерирует настройку NSInMemoryStoreType.
func testCreateUser() {
let container = NSPersistentContainer(name: "Model")
let description = NSPersistentStoreDescription()
description.type = NSInMemoryStoreType
container.persistentStoreDescriptions = [description]
container.loadPersistentStores { _, error in
XCTAssertNil(error)
}
let context = container.viewContext
let user = User(context: context)
user.name = "Иван"
try? context.save()
let fetchRequest: NSFetchRequest<User> = User.fetchRequest()
let users = try? context.fetch(fetchRequest)
XCTAssertEqual(users?.count, 1)
XCTAssertEqual(users?.first?.name, "Иван")
}
Важно: Всегда очищайте in-memory store после каждого теста.
9. Создание SwiftUI-модификатора для анимации появления
Промт: «Создай SwiftUI ViewModifier, который анимирует появление вью с эффектом slide и fade. Длительность 0.3 секунды.»
Пример использования: Для списка задач, где элементы появляются с задержкой. Промт возвращает модификатор с withAnimation.
struct SlideFadeModifier: ViewModifier {
let delay: Double
@State private var isVisible = false
func body(content: Content) -> some View {
content
.opacity(isVisible ? 1 : 0)
.offset(y: isVisible ? 0 : 20)
.onAppear {
withAnimation(.easeOut(duration: 0.3).delay(delay)) {
isVisible = true
}
}
}
}
extension View {
func slideFade(delay: Double = 0) -> some View {
modifier(SlideFadeModifier(delay: delay))
}
}
Результат: Элегантное появление элементов без дополнительных библиотек.
10. Интеграция UIKit в SwiftUI через UIViewRepresentable
Промт: «Оберни UISearchBar в UIViewRepresentable для использования в SwiftUI. Поддержи делегат UISearchBarDelegate.»
Пример использования: В проекте на SwiftUI нужно использовать старый поисковик с кастомной стилизацией. Промт создаёт SearchBarView.
struct SearchBarView: UIViewRepresentable {
@Binding var text: String
func makeUIView(context: Context) -> UISearchBar {
let searchBar = UISearchBar()
searchBar.delegate = context.coordinator
return searchBar
}
func updateUIView(_ uiView: UISearchBar, context: Context) {
uiView.text = text
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
class Coordinator: NSObject, UISearchBarDelegate {
var parent: SearchBarView
init(_ parent: SearchBarView) { self.parent = parent }
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
parent.text = searchText
}
}
}
Совет: Для сложных UIKit-компонентов используйте Coordinator для передачи событий.
Заключение
Эти 10 промтов покрывают основные задачи iOS-разработчика: от генерации UI до работы с данными и анимациями. Сохраняйте их в свой арсенал и адаптируйте под конкретные проекты. Помните: хороший промт — это чёткая формулировка задачи, контекст (версия iOS, фреймворк) и пример ожидаемого результата. Если вы только начинаете использовать AI в разработке, начните с простого — генерации шаблонных вью или тестов. Со временем вы научитесь формулировать запросы так, чтобы получать готовый production-ready код.
Комментарии