Giải pháp điều hướng và quản lý Route với MGJRouter trên iOS

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ư UIImage hoặc NSData.
  • 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;
    }
}

Thẻ: iOS objective-c MGJRouter Mobile-Architecture URL-Routing

Đăng vào ngày 12 tháng 6 lúc 08:19