Вступление
Вы когда-нибудь ловили себя на том, что вместо написания бизнес-логики вы тонете в дебаге нативных модулей? Вчера вы боролись с PlatformException в Flutter на Android 14, сегодня — с NativeModule в React Native, который внезапно перестал работать на iOS 17. Знакомо? По данным опроса Stack Overflow Developer Survey 2025, около 40% разработчиков мобильных приложений называют кроссплатформенные фреймворки одновременно и спасением, и источником головной боли. И это не удивительно: разница в API, версиях ОС и поведении платформ съедает драгоценные часы.
Но что, если превратить эту боль в управляемый процесс? AI-ассистенты уже умеют генерировать код, но без правильных промтов они выдают шаблонные решения, которые не учитывают специфику Flutter или React Native. В этой подборке я собрал 12 промтов, проверенных на реальных проектах. Они разделены на три уровня: базовые (для быстрого старта), продвинутые (для работы с состоянием и навигацией) и экспертные (для нативных модулей и оптимизации). Каждый промт содержит задачу, готовый текст и пример результата. Вы сможете собрать MVP на двух платформах за выходные, а не за две недели.
Базовые промты: генерация экранов и UI
1. Генерация экрана с формой и валидацией
Задача: Создать экран регистрации с полями email и пароль, валидацией и адаптацией под iOS/Android.
Промт:
Ты — senior Flutter разработчик. Сгенерируй виджет RegistrationScreen с полями email и password, используя TextFormField. Добавь валидацию: email должен содержать @ и точку, пароль — минимум 8 символов. Кнопка "Зарегистрироваться" должна быть неактивна, пока форма не валидна. Учти различия: на iOS используй CupertinoTextField, на Android — Material TextField. Приведи полный код с комментариями.
Пример результата:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class RegistrationScreen extends StatefulWidget {
@override
_RegistrationScreenState createState() => _RegistrationScreenState();
}
class _RegistrationScreenState extends State<RegistrationScreen> {
final _formKey = GlobalKey<FormState>();
final _emailController = TextEditingController();
final _passwordController = TextEditingController();
bool _isValid = false;
@override
void initState() {
super.initState();
_emailController.addListener(_validate);
_passwordController.addListener(_validate);
}
void _validate() {
setState(() {
_isValid = _formKey.currentState?.validate() ?? false;
});
}
@override
Widget build(BuildContext context) {
final isIOS = Theme.of(context).platform == TargetPlatform.iOS;
return Scaffold(
appBar: AppBar(title: Text('Регистрация')),
body: Form(
key: _formKey,
child: Padding(
padding: EdgeInsets.all(16),
child: Column(
children: [
isIOS
? CupertinoTextField(
controller: _emailController,
placeholder: 'Email',
keyboardType: TextInputType.emailAddress,
)
: TextFormField(
controller: _emailController,
decoration: InputDecoration(labelText: 'Email'),
validator: (value) {
if (value == null
|| !value.contains('@') || !value.contains('.')) {
return 'Введите корректный email';
}
return null;
},
),
SizedBox(height: 16),
// Аналогично для пароля
ElevatedButton(
onPressed: _isValid ? () {} : null,
child: Text('Зарегистрироваться'),
),
],
),
),
),
);
}
}
2. Адаптивная навигация с BottomNavigationBar
Задача: Сделать нижнюю навигацию, которая выглядит нативно на iOS (TabBar) и Android (BottomNavigationBar).
Промт:
Создай кроссплатформенный виджет MainNavigation с тремя вкладками: Главная, Поиск, Профиль. На iOS используй CupertinoTabBar, на Android — BottomNavigationBar. Обеспечь сохранение состояния каждой вкладки. Напиши код для Flutter.
Пример результата:
class MainNavigation extends StatefulWidget {
@override
_MainNavigationState createState() => _MainNavigationState();
}
class _MainNavigationState extends State<MainNavigation> {
int _currentIndex = 0;
final _pages = [HomePage(), SearchPage(), ProfilePage()];
@override
Widget build(BuildContext context) {
final isIOS = Theme.of(context).platform == TargetPlatform.iOS;
return isIOS
? CupertinoTabScaffold(
tabBar: CupertinoTabBar(
items: [
BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Главная'),
BottomNavigationBarItem(icon: Icon(Icons.search), label: 'Поиск'),
BottomNavigationBarItem(icon: Icon(Icons.person), label: 'Профиль'),
],
onTap: (index) => setState(() => _currentIndex = index),
),
tabBuilder: (context, index) => _pages[index],
)
: Scaffold(
body: _pages[_currentIndex],
bottomNavigationBar: BottomNavigationBar(
currentIndex: _currentIndex,
onTap: (index) => setState(() => _currentIndex = index),
items: [
BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Главная'),
BottomNavigationBarItem(icon: Icon(Icons.search), label: 'Поиск'),
BottomNavigationBarItem(icon: Icon(Icons.person), label: 'Профиль'),
],
),
);
}
}
3. Стилизация под платформу
Задача: Автоматически применять разные цвета и шрифты в зависимости от ОС.
Промт:
Напиши функцию getPlatformStyle(BuildContext context), которая возвращает TextStyle с разными параметрами для iOS (шрифт San Francisco, цвет синий) и Android (шрифт Roboto, цвет зелёный). Используй Theme.of(context).platform.
Пример результата:
TextStyle getPlatformStyle(BuildContext context) {
final platform = Theme.of(context).platform;
if (platform == TargetPlatform.iOS) {
return TextStyle(fontFamily: 'San Francisco', color: Colors.blue);
} else {
return TextStyle(fontFamily: 'Roboto', color: Colors.green);
}
}
Продвинутые промты: состояние и навигация
4. Управление состоянием с Provider
Задача: Реализовать счётчик с сохранением состояния между экранами.
Промт:
Создай ChangeNotifier CounterModel с полем count и методами increment/decrement. Настрой Provider в main.dart. Сделай два экрана: первый отображает счётчик и кнопки, второй — только значение. При переходе между экранами значение должно сохраняться.
Пример результата:
class CounterModel extends ChangeNotifier {
int _count = 0;
int get count => _count;
void increment() { _count++; notifyListeners(); }
void decrement() { _count--; notifyListeners(); }
}
void main() {
runApp(
ChangeNotifierProvider(
create: (_) => CounterModel(),
child: MyApp(),
),
);
}
5. Навигация с передачей параметров
Задача: Перейти на экран деталей, передав объект.
Промт:
Настрой навигацию в Flutter: с экрана списка товаров перейти на экран деталей, передав объект Product. Используй MaterialPageRoute. Покажи, как принять параметр в DetailScreen.
Пример результата:
Navigator.push(
context,
MaterialPageRoute(builder: (context) => DetailScreen(product: product)),
);
class DetailScreen extends StatelessWidget {
final Product product;
DetailScreen({required this.product});
@override
Widget build(BuildContext context) {
return Scaffold(appBar: AppBar(title: Text(product.name)));
}
}
6. Асинхронная загрузка данных с индикатором
Задача: Загрузить список с API и показать CircularProgressIndicator, пока идёт загрузка.
Промт:
Создай экран, который при запуске делает GET-запрос к https://jsonplaceholder.typicode.com/posts и отображает список. Пока данные грузятся, показывай CircularProgressIndicator. При ошибке — SnackBar с сообщением. Используй FutureBuilder.
Пример результата:
FutureBuilder<List<dynamic>>(
future: http.get(Uri.parse('https://jsonplaceholder.typicode.com/posts')).then((res) => json.decode(res.body)),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
} else if (snapshot.hasError) {
return Center(child: Text('Ошибка: ${snapshot.error}'));
} else {
return ListView.builder(
itemCount: snapshot.data!.length,
itemBuilder: (context, index) => ListTile(title: Text(snapshot.data![index]['title'])),
);
}
},
)
Экспертные промты: нативные модули и оптимизация
7. Вызов нативного кода на Swift/Kotlin
Задача: Получить версию ОС через платформенный канал.
Промт:
Напиши MethodChannel для получения версии ОС. На стороне Flutter вызови метод getOSVersion. На iOS реализуй на Swift, на Android — на Kotlin. Верни строку.
Пример результата (Flutter):
static const platform = MethodChannel('app.version');
Future<String> getOSVersion() async {
final String version = await platform.invokeMethod('getOSVersion');
return version;
}
iOS (Swift):
let controller = window?.rootViewController as! FlutterViewController
let channel = FlutterMethodChannel(name: "app.version", binaryMessenger: controller.binaryMessenger)
channel.setMethodCallHandler { (call, result) in
if call.method == "getOSVersion" {
result(UIDevice.current.systemVersion)
}
}
Android (Kotlin):
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, "app.version").setMethodCallHandler { call, result ->
if (call.method == "getOSVersion") {
result.success(android.os.Build.VERSION.RELEASE)
}
}
8. Оптимизация производительности списка
Задача: Улучшить рендеринг длинного списка с изображениями.
Промт:
У меня есть ListView с 1000 элементов, каждый содержит изображение из сети. Он тормозит. Предложи оптимизацию: используй кеширование изображений и ListView.builder. Напиши улучшенный код.
Пример результата:
CachedNetworkImage(
imageUrl: item.imageUrl,
placeholder: (context, url) => CircularProgressIndicator(),
errorWidget: (context, url, error) => Icon(Icons.error),
)
(Используется пакет cached_network_image)
9. Работа с разрешениями (permissions)
Задача: Запросить разрешение на камеру на обеих платформах.
Промт:
Напиши код для запроса разрешения на камеру в Flutter с использованием пакета permission_handler. Учти различия: на iOS нужно добавить NSCameraUsageDescription в Info.plist, на Android — в AndroidManifest.xml. Покажи пример запроса и обработки отказа.
Пример результата:
final status = await Permission.camera.request();
if (status.isGranted) {
// открыть камеру
} else if (status.isDenied) {
showDialog(...);
}
10. Сборка релиза с Flutter build
Задача: Настроить сборку для iOS и Android с разными иконками и названиями.
Промт:
Покажи, как настроить flutter_launcher_icons и flutter_native_splash для генерации иконок и сплэш-скринов под iOS и Android. Напиши конфигурацию в pubspec.yaml.
Пример результата:
flutter_icons:
android: true
ios: true
image_path: "assets/icon.png"
11. Интеграция с React Native: навигация с React Navigation
Задача: Создать стек-навигацию в React Native.
Промт:
Ты — React Native разработчик. Сгенерируй код для StackNavigator с двумя экранами: Home и Details. Используй @react-navigation/native и @react-navigation/stack. Передай параметр с Home на Details.
Пример результата:
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
const Stack = createStackNavigator();
function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Details" component={DetailsScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}
// HomeScreen: navigation.navigate('Details', { itemId: 42 })
// DetailsScreen: const { itemId } = route.params;
12. Отладка нативных ошибок
Задача: Понять, почему падает приложение на Android при вызове нативного модуля.
Промт:
Моё React Native приложение крашится на Android с ошибкой "Native module cannot be null". Как исправить? Объясни причину и дай пошаговое решение.
Пример результата:
Ошибка возникает, когда модуль не зарегистрирован в MainApplication.java. Нужно добавить пакет в список packages. Пример кода:
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new MyCustomPackage() // добавить сюда
);
}
Заключение
Эти 12 промтов покрывают ключевые этапы разработки кроссплатформенного приложения: от генерации UI до работы с нативными модулями. Они не заменят понимания фреймворков, но значительно ускорят рутину. Помните: AI-ассистент — это инструмент, который усиливает ваши навыки, а не заменяет их. Начните с базовых промтов, постепенно переходите к экспертным. И тогда MVP на двух платформах за выходные перестанет быть фантастикой.
Попробуйте применить хотя бы три промта из этой подборки в своём следующем проекте — и сравните время сборки. Делитесь результатами в комментариях.
Источники:
- Официальная документация Flutter: https://flutter.dev/docs
- Официальная документация React Native: https://reactnative.dev/docs
- Stack Overflow Developer Survey 2025: https://survey.stackoverflow.co/2025/
Комментарии