208 lines
7.2 KiB
Markdown
208 lines
7.2 KiB
Markdown
# App Client Base Swift
|
|
|
|
> Ứng dụng iOS native cho nền tảng GoodGo, xây dựng bằng Swift và SwiftUI theo kiến trúc MVVM.
|
|
|
|
## 📱 Tính Năng
|
|
|
|
| Tính năng | Mô tả |
|
|
|-----------|-------|
|
|
| 🔐 Xác thực | Đăng nhập, Đăng ký, Quên mật khẩu với form validation |
|
|
| 🏠 Trang chủ | Lời chào động, Items nổi bật, Feed hoạt động |
|
|
| 🔍 Khám phá | Tìm kiếm địa điểm và dịch vụ |
|
|
| 👤 Hồ sơ | Quản lý thông tin cá nhân và cài đặt |
|
|
| 🌓 Chế độ tối | Hỗ trợ dark mode tự động |
|
|
| 🌐 Đa ngôn ngữ | Hỗ trợ Tiếng Việt & Tiếng Anh |
|
|
|
|
## 🛠️ Công Nghệ
|
|
|
|
| Công nghệ | Phiên bản | Mục đích |
|
|
|-----------|-----------|----------|
|
|
| Swift | 5.9+ | Ngôn ngữ chính |
|
|
| SwiftUI | iOS 15+ | UI Framework declarative |
|
|
| Xcode | 15.0+ | IDE phát triển |
|
|
| URLSession | Native | HTTP networking |
|
|
| Keychain | Native | Lưu trữ token bảo mật |
|
|
| Combine | Native | Reactive programming |
|
|
|
|
## 📋 Yêu Cầu
|
|
|
|
- **macOS**: 14.0+ (Sonoma)
|
|
- **Xcode**: 15.0+
|
|
- **iOS Target**: 15.0+
|
|
- **Tài khoản Apple Developer**: Cần thiết để deploy lên thiết bị
|
|
|
|
## 🚀 Bắt Đầu Nhanh
|
|
|
|
### 1. Clone và mở project
|
|
```bash
|
|
cd apps/app-client-base-swift
|
|
open AppClientBaseSwift/AppClientBaseSwift.xcodeproj
|
|
```
|
|
|
|
### 2. Chọn Simulator
|
|
- Menu Xcode: **Product > Destination > iPhone 15 Pro** (hoặc simulator khác)
|
|
|
|
### 3. Build và Run
|
|
```bash
|
|
# Sử dụng shortcut
|
|
⌘R (Command + R)
|
|
|
|
# Hoặc từ terminal
|
|
xcodebuild -project AppClientBaseSwift/AppClientBaseSwift.xcodeproj \
|
|
-scheme AppClientBaseSwift \
|
|
-destination 'platform=iOS Simulator,name=iPhone 15 Pro' \
|
|
build
|
|
```
|
|
|
|
### 4. Mock Login (để test)
|
|
```
|
|
Email: admin@goodgo.com
|
|
Password: 123456
|
|
```
|
|
|
|
## 📂 Cấu Trúc Project
|
|
|
|
```
|
|
AppClientBaseSwift/
|
|
├── App/
|
|
│ └── AppClientBaseSwiftApp.swift # Entry point @main
|
|
│
|
|
├── Core/
|
|
│ ├── Constants/
|
|
│ │ └── Constants.swift # API, App, Storage, DesignSystem
|
|
│ └── Extensions/
|
|
│ ├── View+Extensions.swift # SwiftUI modifiers
|
|
│ └── String+Extensions.swift # Validation, formatting
|
|
│
|
|
├── Models/
|
|
│ └── User.swift # Entity User + extensions
|
|
│
|
|
├── ViewModels/ # MVVM ViewModels
|
|
│ ├── AuthViewModel.swift # Login/Đăng ký/Quên mật khẩu
|
|
│ ├── HomeViewModel.swift # Logic màn hình Home
|
|
│ └── ProfileViewModel.swift # Quản lý hồ sơ
|
|
│
|
|
├── Views/
|
|
│ ├── Auth/ # Màn hình xác thực
|
|
│ ├── Home/ # Components trang chủ
|
|
│ └── Screens/ # Màn hình chính
|
|
│
|
|
├── Services/
|
|
│ ├── APIService.swift # HTTP client với URLSession
|
|
│ └── AuthManager.swift # Auth state + Keychain
|
|
│
|
|
└── Resources/
|
|
├── Assets.xcassets/ # Hình ảnh & Màu sắc
|
|
├── en.lproj/ # Bản địa hóa Tiếng Anh
|
|
└── vi.lproj/ # Bản địa hóa Tiếng Việt
|
|
```
|
|
|
|
## 🎨 Kiến Trúc
|
|
|
|
### Pattern MVVM
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────┐
|
|
│ VIEW (SwiftUI) │
|
|
│ HomeView, ProfileView, AuthContainerView, LoginView... │
|
|
├─────────────────────────────────────────────────────────────┤
|
|
│ @StateObject / @EnvironmentObject │
|
|
├─────────────────────────────────────────────────────────────┤
|
|
│ VIEWMODEL (ObservableObject) │
|
|
│ HomeViewModel, AuthViewModel, ProfileViewModel │
|
|
│ • Thuộc tính @Published cho reactive UI │
|
|
│ • Phương thức async/await để tải dữ liệu │
|
|
├─────────────────────────────────────────────────────────────┤
|
|
│ Dependency Injection dựa trên Protocol │
|
|
├─────────────────────────────────────────────────────────────┤
|
|
│ SERVICES │
|
|
│ APIService (HTTP) • AuthManager (Auth State + Keychain) │
|
|
└─────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
## 📋 Quy Ước Code
|
|
|
|
### Cấu trúc File
|
|
```swift
|
|
// MARK: - Imports
|
|
import SwiftUI
|
|
|
|
// MARK: - Định nghĩa Type
|
|
/// Mô tả bằng tiếng Việt
|
|
struct/class/enum TypeName {
|
|
// MARK: - Properties
|
|
// MARK: - Init
|
|
// MARK: - Public Methods
|
|
// MARK: - Private Methods
|
|
}
|
|
```
|
|
|
|
### Pattern ViewModel
|
|
```swift
|
|
@MainActor
|
|
final class FeatureViewModel: ObservableObject {
|
|
@Published var isLoading = false
|
|
@Published var errorMessage: String?
|
|
|
|
private let apiService: APIServiceProtocol
|
|
|
|
init(apiService: APIServiceProtocol = APIService.shared) {
|
|
self.apiService = apiService
|
|
}
|
|
|
|
func loadData() async {
|
|
isLoading = true
|
|
defer { isLoading = false }
|
|
// ...
|
|
}
|
|
}
|
|
```
|
|
|
|
## ⚙️ Cấu Hình
|
|
|
|
### Cấu hình API
|
|
```swift
|
|
enum APIConfig {
|
|
static let baseURL = "https://api.goodgo.vn"
|
|
static let apiVersion = "/api/v1"
|
|
static let timeout: TimeInterval = 30.0
|
|
}
|
|
```
|
|
|
|
## 🧪 Kiểm Thử
|
|
|
|
```bash
|
|
xcodebuild test \
|
|
-project AppClientBaseSwift/AppClientBaseSwift.xcodeproj \
|
|
-scheme AppClientBaseSwift \
|
|
-destination 'platform=iOS Simulator,name=iPhone 15 Pro'
|
|
```
|
|
|
|
## 🔐 Bảo Mật
|
|
|
|
| Tính năng | Triển khai |
|
|
|-----------|------------|
|
|
| Lưu trữ Token | Keychain Services (không dùng UserDefaults) |
|
|
| Request bảo mật | Chỉ HTTPS, xác thực Bearer token |
|
|
| Quản lý Session | Tự động refresh token, logout an toàn |
|
|
| Bảo vệ dữ liệu | Mã hóa dữ liệu nhạy cảm khi lưu trữ |
|
|
|
|
## 📱 Thiết Bị Hỗ Trợ
|
|
|
|
- **iPhone**: 8 trở lên (iOS 15+)
|
|
- **iPad**: Tất cả iPad với iOS 15+
|
|
- **Hướng màn hình**: Portrait (chính), Landscape (hỗ trợ)
|
|
|
|
## 🔗 Dự Án Liên Quan
|
|
|
|
- [app-client-base-net](../app-client-base-net) - Client đa nền tảng .NET MAUI
|
|
- [iam-service-net](../../services/iam-service-net) - Backend xác thực
|
|
|
|
## 📚 Tài Liệu Bổ Sung
|
|
|
|
- [Hướng dẫn Kiến trúc](./architecture.md) - Chi tiết kiến trúc và quyết định thiết kế
|
|
|
|
## 📄 Giấy Phép
|
|
|
|
Bản quyền © 2026 GoodGo. Bảo lưu mọi quyền.
|