Retrospective of Ara
I developed Ara, the official KAIST community app, using Flutter. It took six months to complete, and version 1.0.0 was launched on February 22, 2024.
1. Key Implementation Requirements
The web-based Ara frontend and backend have been in service since 1991. However, there was no mobile app for Ara, so I developed one.
Login Logic: Integrate KAIST SSO authentication so that only KAIST students can log in.
Post Viewing: Users should be able to view posts organized by boards
Post Creation and Editing: Users can add and edit posts in HTML format, with support for attachments.
Comments: Enable users to comment on posts.
Multilingual Design: The interface should support both English and Korean.
2. Why do I choose Flutter to implement a mobile app.
2.1 Pros
Previous Experience: My co-worker Sang-oh Kim and I have some familiarity with Flutter.
Cross-Platform: Since the app needs to be available on both iOS and Android, Flutter is a good option.
2.2 Cons
Not Native app: Using advanced and the latest native features can be challenging. I rely solely on the Flutter SDK and its latest updates.
Relatively Small Flutter Community: Fewer available libraries and community resources.
3. Structure
3.1 Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
NEW-ARA-APP
├── ios
│ ├── ...
│ └── fastlane
│ ├── Appfile
│ ├── Fastfile
│ ├── README.md
│ └── report.xml
├── android
│ ├── ...
│ └── fastlane
│ ├── Appfile
│ ├── Fastfile
│ ├── README.md
│ ├── newara-fastlane.json
│ ├── report.xml
│ └── upload-keystore.jks
├── assets
│ ├── fonts
│ │ └── ...
│ ├── icons
│ │ └── ...
│ ├── images
│ │ └── ...
│ └── translations
│ ├── en.json
│ └── ko.json
└── lib
├── constants
│ ├── colors_info.dart
│ └── ...
├── main.dart
├── models
│ ├── article_list_action_model.dart
│ └── ...
├── pages
│ ├── board_list_page.dart
│ └── ...
├── providers
│ ├── user_provider.dart
│ └── ...
├── translations
│ ├── codegen_loader.g.dart
│ └── locale_keys.g.dart
├── utils
│ ├── cache_function.dart
│ └── ...
└── widgets
├── border_boxes.dart
└── ...
- CI/CD is managed by GitHub Actions and fastlane. Deployment keys, such as .jks files, are securely stored in GitHub Secrets.
- assets/: It is composed of images, fonts, and translations.
- lib/models/: It defined the schemas for API requests and response.
- lib/pages/: It contains the structure of pages displayed in the app.
- lib/providers/: Provider is official state management libraries. Each dart file manages an entity’s state.
- lib/widgets/: It contains reusable, common widgets.
3.2 Provider
I used the Provider library to share the same instance across the entire app. It seems like a singleton pattern, but it can also use dependency injection.
Sample
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'cart_provider.dart';
import 'cart_screen.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => CartProvider()),
],
child: CartScreen(), // CartProvider is only available for CartScreen and its widget tree
),
);
}
}
3.3 Role
We divide roles by features.
- Sang-oh Kim: Responsible for implementing the comment writing system, personal profile editing, scrap system, and CI/CD.
- Me: Responsible for implementing the post and board view system, login system, and post writing system.
4. How to implement login
The login page is composed of a Web View. To use Ara app, users must log in through the SPARCS SSO web page, which serves as a club-based SSO system.
SPARCS SSO authenticates by storing cookies in the web browser, making a WebView essential. This includes cookies like csrftoken and sessionId for user authentication and session maintenance.
Interestingly, Flutter allows access to WebView cookies, which could pose a security risk. I’ll address why the authority of cookies is important at a later time.
5. Post Creation and Editing
6. Post Viewing
7. Trouble shooting with app store and play store
8. CI/CD
To be written…
9. Missing Points
After finishing the project, I identified several missing points and learned the following development considerations.
9.1 MVC
If I were to implement the code again, I would solidify the MVC (Model-View-Controller) pattern. However, current code is mixed within dart files in a page folder. I would restructure it as shown below.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
lib/
├── main.dart
├── models/
│ ├── user_model.dart
│ └── product_model.dart
├── views/
│ ├── home_view.dart
│ ├── login_view.dart
│ └── widgets/
│ ├── custom_button.dart
│ └── product_card.dart
├── controllers/
│ ├── user_controller.dart
│ └── product_controller.dart
├── api_service/
│ ├─ schemas.dart
│ └── dio.dart
└── utils/
├── constants.dart
└── helpers.dart
- models/: It stores data and state of the app.
- views/: It is directly related with UI of the app.
- controllers/: It overrides ChangeNotifier and controls data of models. When the model changes, controllers call
notifyListeners()
and update the views. - api_service/: It defines schemas of API and API functions.
9.2 Code Push
Flutter doesn’t support Code Push, which means updating the app takes too long due to app store review processes. This is a key reason that new team members are migrating it to React Native, as Code Push would allow immediate updates without a cumbersome review.
9.3 Native App needed to run in apple watch
If I want to implement app for Apple watch, eventually I have to implement swift code. I noticed that sophisticated app required native code.
9.4 TDD (Test-Driven Development)
Waterfall
It’s challenging to find bugs in the app. Our app follows a development cycle like the graph below:
graph LR
A[Gather requirements] --> B[Analysis and design]
B[Analysis and design] --> C[Code]
C[Code] --> D[Test]
D[Test] --> C[Code]
D[Test] --> E[Deployment]
TDD
While TDD (Test-Driven Development) isn’t absolutely essential, it could be beneficial for effectively catching bugs and organizing features more clearly.
graph LR
A[Gather requirements] --> B[Analysis and design]
B[Analysis and design] --> C[Code]
C[Write test code] --> D[Write feature code]
D --> E[Test]
E --> D
E --> F[Deployment]