MGJRouter là một thư viện hỗ trợ điều hướng trong ứng dụng iOS dựa trên cơ chế URL-block. Tuy nhiên, khi triển khai thực tế, phương pháp này bộc lộ một số nhược điểm cần được xem xét kỹ lưỡng:
- Chi phí bộ nhớ: Việc duy trì một bảng tra cứu URL-block liên tục trong bộ nhớ có thể gây áp lực khi số lượng module tăng lên.
- Hạn chế về kiểu dữ liệu: Theo thiết kế gốc, các tham số qua URL thường bị giới hạn ở dạng chuỗi, gây khó khăn khi cần truyền tải các đối tượng phức tạp như
UIImagehoặcNSData. - Thiếu phân biệt ngữ cảnh: Không có sự tách biệt rõ ràng giữa lời gọi nội bộ (local) và lời gọi từ bên ngoài (remote), dẫn đến các rủi ro bảo mật hoặc hạn chế tính năng khi xử lý URL từ bên ngoài.
- Độ phụ thuộc cao: Các thành phần trong hệ thống phải phụ thuộc trực tiếp vào middleware và việc đăng ký phân tán dễ gây ra tình trạng mã nguồn bị chồng chéo.
1. Cấu trúc hằng số định nghĩa Route
Để quản lý tập trung, chúng ta khởi tạo một lớp cấu hình để định nghĩa các URL Scheme dưới dạng hằng số.
Tệp tin AppRouteDefinition.h:
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
// Định nghĩa URL cho trang cài đặt hệ thống
extern NSString *const kRouteUserConfiguration;
Tệp tin AppRouteDefinition.m:
#import "AppRouteDefinition.h"
NSString *const kRouteUserConfiguration = @"myapp://native/UserConfigurationViewController";
2. Cơ chế đăng ký Route tại Component
Tại mỗi ViewController hoặc Module, chúng ta thực hiện đăng ký logic khởi tạo vào bảng định tuyến thông qua phương thức +load.
+ (void)load {
[MGJRouter registerURLPattern:kRouteUserConfiguration toHandler:^(NSDictionary *routerParameters) {
UserConfigurationViewController *configVC = [[UserConfigurationViewController alloc] init];
// Lấy NavigationController hiện tại để thực hiện điều hướng
UINavigationController *nav = [self currentTopNavigationController];
[nav pushViewController:configVC animated:YES];
}];
}
3. Thực hiện điều hướng và truyền dữ liệu
Khi cần chuyển từ một màn hình bất kỳ sang trang Cài đặt và gửi kèm thông tin người dùng:
NSDictionary *params = @{@"userName": @"NguyenVanA", @"userId": @(123)};
[MGJRouter openURL:kRouteUserConfiguration
withUserInfo:params
completion:^(id result) {
// Xử lý sau khi điều hướng thành công
}];
Tại phía nhận (trang được điều hướng), dữ liệu sẽ được trích xuất từ routerParameters:
NSDictionary *dataReceived = routerParameters[MGJRouterParameterUserInfo];
NSString *name = dataReceived[@"userName"];
4. Xử lý dữ liệu phản hồi (Callback)
Trong trường hợp màn hình đích cần gửi dữ liệu ngược lại cho màn hình gọi, chúng ta sử dụng khối lệnh block.
Tại lớp UserConfigurationViewController:
@property (nonatomic, copy) void (^onStatusChanged)(NSString *status);
Trong khối registerURLPattern:
configVC.onStatusChanged = routerParameters[MGJRouterParameterCompletion];
Khi thực hiện hành động cần trả về dữ liệu:
if (self.onStatusChanged) {
self.onStatusChanged(@"Update_Success");
}
5. Xây dựng bộ điều hướng tổng hợp
Để tối ưu hóa, chúng ta nên xây dựng một phương thức chung để xử lý đa dạng các loại điều hướng như Native, Webview (H5), hoặc Mini Program dựa trên quy tắc từ Backend.
// Định nghĩa các loại đích đến
NSString *const kRouteInternalH5 = @"myapp://webview?url=";
NSString *const kRouteMiniProgram = @"myapp://miniProgram";
/**
Điều hướng đa năng
@param type 1: Native, 2: H5, 3: MiniApp
@param target Định danh module hoặc URL web
@param extra Thông tin bổ sung (ID chi tiết hoặc đường dẫn MiniApp)
*/
+ (void)performGlobalJumpWithType:(NSInteger)type
target:(NSString *)target
extra:(NSString *)extra {
switch (type) {
case 1: // Native
[MGJRouter openURL:target withUserInfo:@{@"id": extra} completion:nil];
break;
case 2: // H5
{
NSString *webUrl = [NSString stringWithFormat:@"%@%@", kRouteInternalH5, extra];
[MGJRouter openURL:webUrl];
}
break;
case 3: // Mini Program
[MGJRouter openURL:kRouteMiniProgram withUserInfo:@{@"path": extra, @"username": target} completion:nil];
break;
default:
break;
}
}