@buivietphi/skill-mobile-mt 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +482 -0
- package/README.md +528 -0
- package/SKILL.md +1399 -0
- package/android/android-native.md +480 -0
- package/bin/install.mjs +976 -0
- package/flutter/flutter.md +304 -0
- package/humanizer/humanizer-mobile.md +295 -0
- package/ios/ios-native.md +182 -0
- package/package.json +56 -0
- package/react-native/react-native.md +743 -0
- package/shared/agent-rules-template.md +343 -0
- package/shared/ai-dlc-workflow.md +237 -0
- package/shared/anti-patterns.md +407 -0
- package/shared/architecture-intelligence.md +416 -0
- package/shared/bug-detection.md +71 -0
- package/shared/ci-cd.md +423 -0
- package/shared/claude-md-template.md +125 -0
- package/shared/code-review.md +133 -0
- package/shared/common-pitfalls.md +117 -0
- package/shared/document-analysis.md +167 -0
- package/shared/error-recovery.md +467 -0
- package/shared/observability.md +688 -0
- package/shared/offline-first.md +377 -0
- package/shared/performance-prediction.md +210 -0
- package/shared/platform-excellence.md +244 -0
- package/shared/prompt-engineering.md +705 -0
- package/shared/release-checklist.md +82 -0
- package/shared/testing-strategy.md +332 -0
- package/shared/ui-ux-mobile.md +667 -0
- package/shared/version-management.md +526 -0
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
# Flutter — Production Patterns
|
|
2
|
+
|
|
3
|
+
> Battle-tested patterns from production Flutter apps.
|
|
4
|
+
> State: Riverpod (standard)
|
|
5
|
+
> DI: get_it + injectable
|
|
6
|
+
> Networking: Dio + Retrofit, or http
|
|
7
|
+
> Navigation: GoRouter
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Clean Architecture
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
lib/
|
|
15
|
+
├── main.dart # Entry: Firebase init, Hive init, ProviderScope
|
|
16
|
+
├── app/
|
|
17
|
+
│ ├── app.dart # MaterialApp.router
|
|
18
|
+
│ ├── router.dart # GoRouter config
|
|
19
|
+
│ └── theme/
|
|
20
|
+
├── features/
|
|
21
|
+
│ ├── auth/
|
|
22
|
+
│ │ ├── domain/ # Entities + use cases + repository interfaces
|
|
23
|
+
│ │ ├── data/ # Repository impl, API client, DTOs, mappers
|
|
24
|
+
│ │ ├── presentation/ # Screens + widgets
|
|
25
|
+
│ │ └── providers/ # Riverpod providers
|
|
26
|
+
│ └── [feature]/
|
|
27
|
+
│ └── ... (same structure)
|
|
28
|
+
├── shared/
|
|
29
|
+
│ ├── widgets/ # Reusable UI
|
|
30
|
+
│ ├── extensions/
|
|
31
|
+
│ └── utils/
|
|
32
|
+
└── core/
|
|
33
|
+
├── network/ # Dio client setup, interceptors
|
|
34
|
+
├── storage/ # Hive + SharedPrefs + flutter_secure_storage
|
|
35
|
+
├── di/ # get_it + injectable setup
|
|
36
|
+
└── constants/
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Dependency Rule
|
|
40
|
+
```
|
|
41
|
+
presentation/ → domain/ ← data/
|
|
42
|
+
|
|
43
|
+
Presentation depends on Domain. Data depends on Domain.
|
|
44
|
+
Domain depends on NOTHING.
|
|
45
|
+
Never import data/ from presentation/ directly.
|
|
46
|
+
Use cases call repository interfaces (defined in domain/).
|
|
47
|
+
Data layer provides implementations.
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## State Management (Riverpod)
|
|
51
|
+
|
|
52
|
+
```dart
|
|
53
|
+
// domain/usecases/get_products.dart
|
|
54
|
+
class GetProducts {
|
|
55
|
+
final ProductRepository repository;
|
|
56
|
+
GetProducts(this.repository);
|
|
57
|
+
Future<List<Product>> call() => repository.getProducts();
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// features/product/providers/product_providers.dart
|
|
61
|
+
@riverpod
|
|
62
|
+
class ProductList extends _$ProductList {
|
|
63
|
+
@override
|
|
64
|
+
FutureOr<List<Product>> build() async {
|
|
65
|
+
final repo = ref.read(productRepositoryProvider);
|
|
66
|
+
return repo.getProducts();
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
Future<void> refresh() async {
|
|
70
|
+
state = const AsyncLoading();
|
|
71
|
+
state = await AsyncValue.guard(() async {
|
|
72
|
+
final repo = ref.read(productRepositoryProvider);
|
|
73
|
+
return repo.getProducts();
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// features/product/presentation/product_screen.dart
|
|
79
|
+
class ProductScreen extends ConsumerWidget {
|
|
80
|
+
const ProductScreen({super.key});
|
|
81
|
+
|
|
82
|
+
@override
|
|
83
|
+
Widget build(BuildContext context, WidgetRef ref) {
|
|
84
|
+
final products = ref.watch(productListProvider);
|
|
85
|
+
return products.when(
|
|
86
|
+
data: (list) => list.isEmpty
|
|
87
|
+
? const EmptyState()
|
|
88
|
+
: ListView.builder(
|
|
89
|
+
itemCount: list.length,
|
|
90
|
+
itemBuilder: (_, i) => ProductCard(product: list[i]),
|
|
91
|
+
),
|
|
92
|
+
loading: () => const Center(child: CircularProgressIndicator()),
|
|
93
|
+
error: (e, _) => ErrorState(onRetry: () => ref.invalidate(productListProvider)),
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Dependency Injection (get_it + injectable)
|
|
100
|
+
|
|
101
|
+
```dart
|
|
102
|
+
// core/di/injection.dart
|
|
103
|
+
import 'package:get_it/get_it.dart';
|
|
104
|
+
import 'package:injectable/injectable.dart';
|
|
105
|
+
|
|
106
|
+
final getIt = GetIt.instance;
|
|
107
|
+
|
|
108
|
+
@InjectableInit()
|
|
109
|
+
void configureDependencies() => getIt.init();
|
|
110
|
+
|
|
111
|
+
// Usage: annotate classes
|
|
112
|
+
@injectable
|
|
113
|
+
class AuthRepository {
|
|
114
|
+
final ApiClient _client;
|
|
115
|
+
AuthRepository(this._client);
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Navigation (GoRouter)
|
|
120
|
+
|
|
121
|
+
```dart
|
|
122
|
+
final router = GoRouter(
|
|
123
|
+
redirect: (context, state) {
|
|
124
|
+
final isAuth = authNotifier.isAuthenticated;
|
|
125
|
+
final isAuthRoute = state.matchedLocation.startsWith('/auth');
|
|
126
|
+
if (!isAuth && !isAuthRoute) return '/auth/login';
|
|
127
|
+
if (isAuth && isAuthRoute) return '/';
|
|
128
|
+
return null;
|
|
129
|
+
},
|
|
130
|
+
routes: [
|
|
131
|
+
ShellRoute(
|
|
132
|
+
builder: (_, __, child) => MainScaffold(child: child),
|
|
133
|
+
routes: [
|
|
134
|
+
GoRoute(path: '/', builder: (_, __) => const HomeScreen()),
|
|
135
|
+
GoRoute(path: '/profile', builder: (_, __) => const ProfileScreen()),
|
|
136
|
+
],
|
|
137
|
+
),
|
|
138
|
+
GoRoute(path: '/auth/login', builder: (_, __) => const LoginScreen()),
|
|
139
|
+
],
|
|
140
|
+
);
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Networking
|
|
144
|
+
|
|
145
|
+
### Dio + Retrofit
|
|
146
|
+
|
|
147
|
+
```dart
|
|
148
|
+
@RestApi(baseUrl: ApiConstants.baseUrl)
|
|
149
|
+
abstract class ApiClient {
|
|
150
|
+
factory ApiClient(Dio dio) = _ApiClient;
|
|
151
|
+
|
|
152
|
+
@GET('/products')
|
|
153
|
+
Future<ApiResponse<List<ProductDto>>> getProducts();
|
|
154
|
+
|
|
155
|
+
@POST('/auth/login')
|
|
156
|
+
Future<ApiResponse<AuthDto>> login(@Body() LoginInput input);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Dio setup with interceptors
|
|
160
|
+
final dio = Dio(BaseOptions(
|
|
161
|
+
baseUrl: ApiConstants.baseUrl,
|
|
162
|
+
connectTimeout: const Duration(seconds: 15),
|
|
163
|
+
))
|
|
164
|
+
..interceptors.addAll([
|
|
165
|
+
AuthInterceptor(secureStorage),
|
|
166
|
+
PrettyDioLogger(requestBody: true, responseBody: true),
|
|
167
|
+
RetryInterceptor(dio: dio, retries: 2),
|
|
168
|
+
]);
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### HTTP (simpler pattern)
|
|
172
|
+
|
|
173
|
+
```dart
|
|
174
|
+
final response = await http.get(
|
|
175
|
+
Uri.parse('$baseUrl/endpoint'),
|
|
176
|
+
headers: {'Authorization': 'Bearer $token'},
|
|
177
|
+
);
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## Local Storage
|
|
181
|
+
|
|
182
|
+
```dart
|
|
183
|
+
// Hive (structured data)
|
|
184
|
+
await Hive.initFlutter();
|
|
185
|
+
Hive.registerAdapter(UserAdapter());
|
|
186
|
+
final box = await Hive.openBox<User>('users');
|
|
187
|
+
|
|
188
|
+
// Floor (Room-like SQL)
|
|
189
|
+
@dao
|
|
190
|
+
abstract class ProductDao {
|
|
191
|
+
@Query('SELECT * FROM products')
|
|
192
|
+
Future<List<ProductEntity>> getAll();
|
|
193
|
+
|
|
194
|
+
@Insert(onConflict: OnConflictStrategy.replace)
|
|
195
|
+
Future<void> insertAll(List<ProductEntity> products);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// SharedPreferences (simple key-value)
|
|
199
|
+
final prefs = await SharedPreferences.getInstance();
|
|
200
|
+
|
|
201
|
+
// flutter_secure_storage (tokens)
|
|
202
|
+
final storage = const FlutterSecureStorage();
|
|
203
|
+
await storage.write(key: 'token', value: token);
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
## Firebase
|
|
207
|
+
|
|
208
|
+
```dart
|
|
209
|
+
// Firebase init in main.dart
|
|
210
|
+
await Firebase.initializeApp();
|
|
211
|
+
await FirebaseMessaging.instance.requestPermission();
|
|
212
|
+
|
|
213
|
+
// Firestore
|
|
214
|
+
final doc = await FirebaseFirestore.instance.collection('users').doc(uid).get();
|
|
215
|
+
|
|
216
|
+
// FCM push
|
|
217
|
+
FirebaseMessaging.onMessage.listen((message) {
|
|
218
|
+
// Handle foreground notification
|
|
219
|
+
});
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
## Key Libraries
|
|
223
|
+
|
|
224
|
+
| Purpose | Library |
|
|
225
|
+
|---------|---------|
|
|
226
|
+
| State | flutter_riverpod |
|
|
227
|
+
| DI | get_it + injectable |
|
|
228
|
+
| HTTP | dio + retrofit |
|
|
229
|
+
| HTTP | http |
|
|
230
|
+
| DB | floor |
|
|
231
|
+
| DB | hive |
|
|
232
|
+
| Router | go_router |
|
|
233
|
+
| UI | flutter_screenutil |
|
|
234
|
+
| Anim | flutter_animate |
|
|
235
|
+
| Auth | local_auth (biometric) |
|
|
236
|
+
| Crypto | encrypt, crypto |
|
|
237
|
+
| Forms | formz |
|
|
238
|
+
| Func | dartz (Either, Option) |
|
|
239
|
+
| Models | freezed_annotation |
|
|
240
|
+
| Firebase | firebase_core, messaging, firestore |
|
|
241
|
+
| Image | cached_network_image |
|
|
242
|
+
|
|
243
|
+
## Dart 3.x Patterns
|
|
244
|
+
|
|
245
|
+
```dart
|
|
246
|
+
// Sealed classes — exhaustive pattern matching (replaces abstract + subclasses)
|
|
247
|
+
sealed class AuthState {}
|
|
248
|
+
class Authenticated extends AuthState { final User user; Authenticated(this.user); }
|
|
249
|
+
class Unauthenticated extends AuthState {}
|
|
250
|
+
class Loading extends AuthState {}
|
|
251
|
+
|
|
252
|
+
// Usage — compiler enforces all cases are handled
|
|
253
|
+
Widget build() => switch (authState) {
|
|
254
|
+
Authenticated(:final user) => HomeScreen(user: user),
|
|
255
|
+
Unauthenticated() => LoginScreen(),
|
|
256
|
+
Loading() => const CircularProgressIndicator(),
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
// Records — lightweight tuples with named fields (Dart 3.0)
|
|
260
|
+
(String name, int age) getUser() => ('Alice', 30);
|
|
261
|
+
final (name, age) = getUser();
|
|
262
|
+
|
|
263
|
+
// Pattern matching in if/switch
|
|
264
|
+
if (response case {'status': 'ok', 'data': final data}) {
|
|
265
|
+
processData(data);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// Riverpod + sealed class = clean state
|
|
269
|
+
@riverpod
|
|
270
|
+
class AuthNotifier extends _$AuthNotifier {
|
|
271
|
+
@override
|
|
272
|
+
AuthState build() => Unauthenticated();
|
|
273
|
+
|
|
274
|
+
Future<void> login(String email, String password) async {
|
|
275
|
+
state = Loading();
|
|
276
|
+
state = switch (await _repo.login(email, password)) {
|
|
277
|
+
Ok(:final value) => Authenticated(value),
|
|
278
|
+
Err(:final error) => Unauthenticated(), // or a separate Error state
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
## Impeller (Flutter 3.10+)
|
|
285
|
+
|
|
286
|
+
```
|
|
287
|
+
Impeller is Flutter's new rendering engine — enabled by default on iOS.
|
|
288
|
+
Android: opt-in via AndroidManifest.xml
|
|
289
|
+
|
|
290
|
+
Benefits:
|
|
291
|
+
- Eliminates shader compilation jank (the "jank on first frame" problem)
|
|
292
|
+
- Consistent 60/120fps even on first run
|
|
293
|
+
|
|
294
|
+
Enable on Android:
|
|
295
|
+
<meta-data android:name="io.flutter.embedding.android.EnableImpeller" android:value="true" />
|
|
296
|
+
|
|
297
|
+
Test: flutter run --enable-impeller
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
---
|
|
301
|
+
|
|
302
|
+
> Standard: Riverpod + get_it/injectable + Clean Architecture.
|
|
303
|
+
> Dio/Retrofit for complex APIs. Floor for offline-first. Firebase for push/analytics.
|
|
304
|
+
> Dart 3.x: sealed classes + records for type-safe state.
|
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
# Humanizer — Mobile Copy & Text
|
|
2
|
+
|
|
3
|
+
> Invoke with: @humanizer-mobile
|
|
4
|
+
> Use for: app store descriptions, release notes, error messages, onboarding copy, push notifications, UI labels
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## What this does
|
|
9
|
+
|
|
10
|
+
Removes AI-generated writing patterns from mobile app text. Makes copy sound like a real person wrote it — not a language model.
|
|
11
|
+
|
|
12
|
+
**Rule:** Sterile, voiceless writing is just as obvious as slop.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## The 24 AI Patterns to Kill
|
|
17
|
+
|
|
18
|
+
### Content
|
|
19
|
+
| Pattern | Example | Fix |
|
|
20
|
+
|---------|---------|-----|
|
|
21
|
+
| Inflated significance | "This significantly enhances the overall user experience" | "Checkout is now 3 steps instead of 7" |
|
|
22
|
+
| Notability inflation | "A powerful, robust, feature-rich solution" | Just describe what it does |
|
|
23
|
+
| Promotional language | "Seamlessly integrates with your workflow" | "Connects to Slack and Notion" |
|
|
24
|
+
| Superficial -ing analysis | "By leveraging cutting-edge technology..." | State what the tech actually does |
|
|
25
|
+
|
|
26
|
+
### Language
|
|
27
|
+
| Pattern | Example | Fix |
|
|
28
|
+
|---------|---------|-----|
|
|
29
|
+
| Copula avoidance | "The app, being designed for..." | "The app works for..." |
|
|
30
|
+
| Negative parallelism | "Not only fast, but also reliable, and furthermore secure" | Pick the one that matters most |
|
|
31
|
+
| Rule of three | "Simple, powerful, and intuitive" | Say which one is actually true |
|
|
32
|
+
| Elegant variation | "application... software... platform... tool..." | Pick one word and use it |
|
|
33
|
+
|
|
34
|
+
### Style
|
|
35
|
+
| Pattern | Example | Fix |
|
|
36
|
+
|---------|---------|-----|
|
|
37
|
+
| Em dash overuse | "Our app — designed for professionals — helps you..." | Rewrite the sentence |
|
|
38
|
+
| Unnecessary bold | "This **feature** allows **users** to **manage** their **tasks**" | Bold nothing or bold the one key thing |
|
|
39
|
+
| Inline headers mid-paragraph | "**Key features:** The app includes..." | Just write the features |
|
|
40
|
+
| Emoji decoration | "🚀 Fast • 💪 Powerful • ✨ Beautiful" | Use 0 or 1 emoji max, never as decoration |
|
|
41
|
+
|
|
42
|
+
### Communication (chatbot artifacts)
|
|
43
|
+
| Pattern | Example | Fix |
|
|
44
|
+
|---------|---------|-----|
|
|
45
|
+
| "I hope this helps" | Any form of it | Delete |
|
|
46
|
+
| "Feel free to..." | "Feel free to reach out" | "Contact us" |
|
|
47
|
+
| "Please note that" | "Please note that this feature requires..." | "This feature requires..." |
|
|
48
|
+
| Knowledge cutoff disclaimer | "As of my last update..." | Never use in app copy |
|
|
49
|
+
| "Delve into" | "Delve into your analytics" | "Check your analytics" |
|
|
50
|
+
| "Leverage" | "Leverage our AI" | "Use our AI" |
|
|
51
|
+
| "Streamline" | "Streamline your workflow" | Say what actually gets faster |
|
|
52
|
+
| "Robust" | "A robust solution" | Say what makes it strong |
|
|
53
|
+
| "Seamlessly" | "Seamlessly integrates" | "Works with" or just remove |
|
|
54
|
+
| "Intuitive" | "Intuitive interface" | Show don't tell — describe the UX |
|
|
55
|
+
| "Comprehensive" | "Comprehensive dashboard" | Say what's in the dashboard |
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Mobile-Specific Rewrites
|
|
60
|
+
|
|
61
|
+
### App Store Description
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
❌ AI:
|
|
65
|
+
TaskFlow is a powerful, comprehensive task management application that seamlessly
|
|
66
|
+
integrates with your existing workflow. By leveraging cutting-edge AI technology,
|
|
67
|
+
it significantly enhances productivity and streamlines your daily operations.
|
|
68
|
+
|
|
69
|
+
✅ Human:
|
|
70
|
+
TaskFlow keeps your team's work in one place. Add tasks, assign them, set
|
|
71
|
+
deadlines — everything syncs in real time. Works with Slack, Google Calendar,
|
|
72
|
+
and Notion.
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Release Notes
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
❌ AI:
|
|
79
|
+
Version 2.1.0 introduces significant enhancements to the overall user experience,
|
|
80
|
+
including robust improvements to performance and reliability.
|
|
81
|
+
|
|
82
|
+
✅ Human:
|
|
83
|
+
2.1.0
|
|
84
|
+
- Faster load times on older Android devices (was 4s, now 1.2s)
|
|
85
|
+
- Fixed crash when opening notifications while offline
|
|
86
|
+
- Dark mode now remembers your setting between sessions
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Error Messages
|
|
90
|
+
|
|
91
|
+
```
|
|
92
|
+
❌ AI:
|
|
93
|
+
We apologize for the inconvenience. An unexpected error has occurred while
|
|
94
|
+
processing your request. Please try again later.
|
|
95
|
+
|
|
96
|
+
✅ Human:
|
|
97
|
+
Couldn't save your changes — no internet connection.
|
|
98
|
+
[Try again] [Save for later]
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Onboarding Copy
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
❌ AI:
|
|
105
|
+
Welcome to our powerful platform! By leveraging our intuitive interface,
|
|
106
|
+
you'll be able to seamlessly manage all your tasks efficiently.
|
|
107
|
+
|
|
108
|
+
✅ Human:
|
|
109
|
+
Where do you want to start?
|
|
110
|
+
[Import from Trello] [Start from scratch] [Use a template]
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Push Notifications
|
|
114
|
+
|
|
115
|
+
```
|
|
116
|
+
❌ AI:
|
|
117
|
+
You have received a new message from a team member regarding an important update.
|
|
118
|
+
|
|
119
|
+
✅ Human:
|
|
120
|
+
Alex commented on "Landing page redesign"
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Empty States
|
|
124
|
+
|
|
125
|
+
```
|
|
126
|
+
❌ AI:
|
|
127
|
+
No items found. Get started by creating your first item to begin
|
|
128
|
+
leveraging the full power of the platform.
|
|
129
|
+
|
|
130
|
+
✅ Human:
|
|
131
|
+
No tasks yet.
|
|
132
|
+
[Add your first task]
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## Two-Pass Process
|
|
138
|
+
|
|
139
|
+
### Pass 1 — Rewrite
|
|
140
|
+
1. Find all patterns from the table above
|
|
141
|
+
2. Replace each with direct, specific language
|
|
142
|
+
3. Remove filler words: "overall", "various", "multiple", "utilize", "leverage"
|
|
143
|
+
4. Cut sentence length by 30%
|
|
144
|
+
|
|
145
|
+
### Pass 2 — Anti-AI Audit
|
|
146
|
+
Ask: *"What makes this obviously AI-generated?"*
|
|
147
|
+
- Does it make a claim without evidence? → Add a number or cut the claim
|
|
148
|
+
- Does it use an adjective where a verb would work? → Use the verb
|
|
149
|
+
- Could this describe any app in the category? → Make it specific to THIS app
|
|
150
|
+
- Would a person actually say this out loud? → If no, rewrite it
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## Mobile Copy Principles
|
|
155
|
+
|
|
156
|
+
```
|
|
157
|
+
1. SPECIFIC BEATS VAGUE
|
|
158
|
+
❌ "significantly faster"
|
|
159
|
+
✅ "loads in under 1 second"
|
|
160
|
+
|
|
161
|
+
2. VERBS BEAT ADJECTIVES
|
|
162
|
+
❌ "intuitive navigation"
|
|
163
|
+
✅ "swipe left to archive"
|
|
164
|
+
|
|
165
|
+
3. SHORT SENTENCES FOR MOBILE
|
|
166
|
+
Max 12 words for notifications
|
|
167
|
+
Max 2 sentences for error messages
|
|
168
|
+
Max 3 sentences for onboarding screens
|
|
169
|
+
|
|
170
|
+
4. SHOW DON'T TELL
|
|
171
|
+
❌ "powerful search"
|
|
172
|
+
✅ "search by name, tag, due date, or assignee"
|
|
173
|
+
|
|
174
|
+
5. USER BENEFIT, NOT FEATURE
|
|
175
|
+
❌ "real-time sync enabled"
|
|
176
|
+
✅ "your team sees changes instantly"
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
## App Store Character Limits
|
|
182
|
+
|
|
183
|
+
```
|
|
184
|
+
iOS App Store:
|
|
185
|
+
Title: 30 chars → short, keyword-rich, no taglines
|
|
186
|
+
Subtitle: 30 chars → 1 benefit, not a repeat of title
|
|
187
|
+
Description: 4000 chars → first 3 lines show before "More", make them count
|
|
188
|
+
Keywords: 100 chars → comma-separated, no spaces, no repeats from title
|
|
189
|
+
What's New: 4000 chars → bullet points, plain language, no marketing
|
|
190
|
+
|
|
191
|
+
Google Play:
|
|
192
|
+
Title: 30 chars
|
|
193
|
+
Short desc: 80 chars → shows in search results
|
|
194
|
+
Full desc: 4000 chars
|
|
195
|
+
What's New: 500 chars
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
```
|
|
199
|
+
❌ Title: "TaskFlow - Ultimate Productivity & Task Management Solution"
|
|
200
|
+
✅ Title: "TaskFlow: Team Tasks & Projects"
|
|
201
|
+
|
|
202
|
+
❌ Subtitle: "The most powerful way to manage your workflow seamlessly"
|
|
203
|
+
✅ Subtitle: "Shared tasks with real-time sync"
|
|
204
|
+
|
|
205
|
+
❌ What's New: "This update introduces significant improvements to the overall
|
|
206
|
+
user experience with enhanced performance and reliability."
|
|
207
|
+
✅ What's New:
|
|
208
|
+
• Fixed crash on iPhone 14 when swiping between projects
|
|
209
|
+
• Dark mode now loads instantly instead of flashing white
|
|
210
|
+
• Added swipe-to-complete on task cards
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
## Permission Request Copy
|
|
216
|
+
|
|
217
|
+
```
|
|
218
|
+
❌ AI default (iOS):
|
|
219
|
+
"[App] Would Like to Access Your Camera"
|
|
220
|
+
(No context, user taps Don't Allow)
|
|
221
|
+
|
|
222
|
+
✅ Custom NSCameraUsageDescription:
|
|
223
|
+
"To scan receipts and attach photos to expenses"
|
|
224
|
+
|
|
225
|
+
❌ "Notifications" permission with no context
|
|
226
|
+
|
|
227
|
+
✅ Request at the right moment + explain:
|
|
228
|
+
"Get notified when teammates comment on your tasks"
|
|
229
|
+
[Allow] [Not now]
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
Common permission descriptions:
|
|
233
|
+
| Permission | Bad | Good |
|
|
234
|
+
|------------|-----|------|
|
|
235
|
+
| Camera | "Access camera" | "Scan QR codes to join a workspace" |
|
|
236
|
+
| Location | "Use your location" | "Show nearby team members on the map" |
|
|
237
|
+
| Contacts | "Access contacts" | "Invite teammates by name instead of email" |
|
|
238
|
+
| Notifications | "Send notifications" | "Alert you when your order ships" |
|
|
239
|
+
| Microphone | "Access microphone" | "Record voice notes on tasks" |
|
|
240
|
+
|
|
241
|
+
---
|
|
242
|
+
|
|
243
|
+
## Rating Prompt Copy
|
|
244
|
+
|
|
245
|
+
```
|
|
246
|
+
❌ AI default:
|
|
247
|
+
"Are you enjoying [App Name]? Rate us 5 stars!"
|
|
248
|
+
|
|
249
|
+
✅ Human — ask a real question first:
|
|
250
|
+
"Is [App] helping you get things done?"
|
|
251
|
+
[Yes!] [Not really]
|
|
252
|
+
|
|
253
|
+
If Yes → "Mind leaving a review? It helps us a lot."
|
|
254
|
+
[Sure] [Maybe later]
|
|
255
|
+
If No → "What's getting in the way?"
|
|
256
|
+
[Give feedback]
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
## Subscription & Paywall Copy
|
|
262
|
+
|
|
263
|
+
```
|
|
264
|
+
❌ AI:
|
|
265
|
+
"Unlock the full potential of our comprehensive premium features
|
|
266
|
+
to seamlessly enhance your productivity experience."
|
|
267
|
+
|
|
268
|
+
✅ Human — state what unlocks:
|
|
269
|
+
"Go Pro
|
|
270
|
+
• Unlimited projects (free plan: 3)
|
|
271
|
+
• Team sharing
|
|
272
|
+
• Priority support"
|
|
273
|
+
[Start 7-day free trial]
|
|
274
|
+
[See what's included]
|
|
275
|
+
|
|
276
|
+
❌ CTA: "Subscribe Now" / "Upgrade Today" / "Get Premium"
|
|
277
|
+
✅ CTA: "Start free trial" / "Unlock [specific feature]" / "Try Pro free"
|
|
278
|
+
|
|
279
|
+
❌ After trial ends: "Your trial has expired. Please subscribe to continue."
|
|
280
|
+
✅ "Your free trial ended. Pick a plan to keep your 12 projects."
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
---
|
|
284
|
+
|
|
285
|
+
## Word Blacklist (delete on sight)
|
|
286
|
+
|
|
287
|
+
```
|
|
288
|
+
seamlessly / robust / powerful / comprehensive / intuitive / streamline /
|
|
289
|
+
leverage / utilize / cutting-edge / state-of-the-art / innovative /
|
|
290
|
+
revolutionary / game-changing / transformative / holistic / synergy /
|
|
291
|
+
delve / Furthermore / Additionally / Moreover / In conclusion /
|
|
292
|
+
It is worth noting / Please note that / Feel free to /
|
|
293
|
+
experience the difference / take your [X] to the next level /
|
|
294
|
+
designed with you in mind / your one-stop solution
|
|
295
|
+
```
|