Skip to main content

Tích hợp SDK trên iOS

Requirements

TiniAppSDK là SDK cho ios để biến 1 ios app thành super app. SDK cung cấp các tính năng:

  • Mở 1 Tiniapp bất kì
  • Cấu hình deeplink/universal link để mở TiniApp

TiniAppSDK có thể tích hợp vào các ứng dụng iOS với các điều kiện

  • iOS 9.0 trở lên
  • CocoaPods 1.0 trở lên

Sau bước đăng ký, bạn sẽ nhận được các thông tin

  • partner_code: là một chuỗi duy nhất gắn với từng Super App
  • client_id: là một UUID gắn liền với Super App

partner_codeclient_id phải sử dụng cùng cặp với nhau, các Tini App sẽ không mở được nếu bạn truyền sai partner_codeclient_id.

Ngoài ra, cặp key partner_codeclient_id chỉ có thể sử dụng với các app bundle id mà bạn đã đăng ký. Nếu sử dụng cặp key này trên một app bundle id chưa được đăng ký, các Tini App cũng không thể mở được.

Integration Steps

1. Cài đặt CocoaPod

TiniSDK có thể được cài đặt từ CocoaPod. Nếu bạn đã cài đặt CocoaPod có thể bỏ qua bước này.

Tham khảo về CocoaPod ở đây Link

sudo gem install cocoapods
pod setup

1.1. Tạo Podfile

Nếu đã có Podfile, bạn có thể bỏ qua step này Tạo 1 Podfile, tham khảo cách tạo Podfile ở đây Link

source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '11.0'
target 'ExampleSDK' do
# Comment the next line if you don't want to use dynamic frameworks
use_frameworks!

pod "TiniAppSDK", "~> 1.9.5"

end

post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings.delete 'IPHONEOS_DEPLOYMENT_TARGET'
end

target.build_configurations.each do |config|
config.build_settings['ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES'] = 'NO'
end

if target.respond_to?(:product_type) and target.product_type == "com.apple.product-type.bundle"
target.build_configurations.each do |config|
config.build_settings['CODE_SIGNING_ALLOWED'] = 'NO'
end
end
end
end

1.2. Thêm TiniAppSDK vào Podfile

# ...
pod 'TiniAppSDK', '~> 1.9.5'
# ...

1.3. Install hoặc Update Pod

pod install

hoặc

pod update

2. Cấu hình Info.plist

TiniAppSDK cần 1 số quyền runtime để xin quyền từ user khi cần, nên app của bạn cần add các description cho các quyền tương ứng ở file Info.plist nếu chưa có.

<!-- ... -->
<key>NSCameraUsageDescription</key>
<string>Tini App muốn truy cập camera của bạn</string>
<key>NSContactsUsageDescription</key>
<string>Tini App muốn truy cập danh bạ của bạn</string>
<key>NSFaceIDUsageDescription</key>
<string>Sử dụng FaceID hoặc TouchID để xác thực</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>Tini App muốn sử dụng vị trí của bạn</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>Tini App muốn sử dụng vị trí của bạn</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Tini App muốn sử dụng vị trí của bạn</string>
<key>NSMicrophoneUsageDescription</key>
<string>Tini App muốn truy cập ghi âm của bạn</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>Tini App muốn truy cập thư viện ảnh của bạn</string>
<!-- ... -->
QuyềnTypeJSAPI sử dụng
NSCameraUsageDescriptionCameramy.chooseImage, my.chooseVideo my.scan
NSPhotoLibraryUsageDescriptionCameramy.chooseImage, my.chooseVideo, my.scan, my.saveImage
NSContactsUsageDescriptionContactmy.chooseContact, my.addPhoneContact
NSFaceIDUsageDescriptionBiometricmy.bioMetrics.createKey, my.bioMetrics.createSignature, my.bioMetrics.deleteKey, my.bioMetrics.isSupported, my.bioMetrics.keyExists, my.bioMetrics.localAuth my.getEncryptedStorage, my.setEncryptedStorage
NSLocationAlwaysAndWhenInUseUsageDescriptionLocationmy.getLocation
NSLocationAlwaysUsageDescriptionLocationmy.getLocation
NSLocationWhenInUseUsageDescriptionLocationmy.getLocation
NSMicrophoneUsageDescriptionMicrophonemy.chooseVideo, my.scan

3. Khởi tạo SDK

TiniAppSDK trước khi sử dụng, cần gọi phương thức config một lần duy nhất để khởi tạo SDK. partnerCodeclientId là thông tin đã lấy trước đó từ TiniConsole.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
TiniAppConfiguration *config = [[TiniAppConfiguration alloc] init];
config.partnerCode = @"partner code you get when register";
config.clientId = @"client id you get when register";
config.env = TiniEnvProd;
[TiniAppSDK configWith:config];
TiniAppSDK.sharedInstance.delegate = self;
return YES;
}

4. Mở 1 TiniApp

Để mở 1 tiniapp, chúng ta có thể dùng cách sau:

TiniAppViewController *vc = [[TiniAppSDK sharedInstance] openMiniAppWithAppId:@"vn.tiki.vip" pathPath:nil params:nil];
vc.modalPresentationStyle = UIModalPresentationFullScreen;
[self presentViewController:vc animated:YES completion:nil];

trong đó:

  • appId: Required. Id của tiniapp cần mở
  • pagePath: Optional. Đường dẫn của page cần mở ví dụ pages/home/index
  • params: Optional. Các tham số cần truyền thêm. Các tham số này sẽ nhận ở lifecycle onLaunch của App hoặc onLoad của page

kết quả trả về:

  • TiniAppViewController: Hàm openMiniapp trả về 1 view controller. Chúng ta có thể present hay push view controller này vào stack tuỳ theo mục đích sử dụng

Để có thể mở 1 tiniapp từ deeplink, chúng ta cần implement các phương thức sau ở application delegate

- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
return [[TiniApplicationDelegate sharedInstance] application:application openURL:url options:options];
}

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(nullable NSString *)sourceApplication annotation:(id)annotation {
return [[TiniApplicationDelegate sharedInstance] application:application openURL:url sourceApplication:sourceApplication annotation:annotation];
}

Lưu ý:

  • Deeplink cho tiniapp bắt buộc sẽ có định dạng: scheme://apps/appId/pagePath?params. Ví dụ: tikivn://apps/vn.tiki.vip

6. Cài đặt delegate của TiniAppSDK

TiniAppSDK cung cấp 3 hàm delegate bạn cần implement trong Super App của mình. Bạn cần set delegate cho class được implement

TiniAppSDK.sharedInstance.delegate = self;

//implement các hàm của TiniAppSDKDelegate
- (void)closeAppWithCompletedHandler:(void (NS_NOESCAPE ^)(void))completedHandler {
dispatch_async(dispatch_get_main_queue(), ^{
UIViewController *topController = [UIApplication sharedApplication].keyWindow.rootViewController;
while (topController.presentedViewController) {
topController = topController.presentedViewController;
}
[topController dismissViewControllerAnimated:YES completion:nil];
});
}

- (void)getUserInfoWithCompletedHandler:(void (NS_NOESCAPE ^ _Nonnull)(TiniUser* _Nullable, NSError * _Nullable))completedHandler {
TiniUser *user = [[TiniUser alloc] initWithId:@"1234" name:@"Test user" email:@"test@gmail.com" phoneNumber:@"0123456789"];
completedHandler(user, nil);
}


- (void)openPaymentWithTransactionId:(NSString * _Nonnull)transactionId amount:(double)amount completedHandler:(void (^ _Nonnull)(NSDictionary<NSString *,id> * _Nullable, NSError * _Nullable))completedHandler {
dispatch_async(dispatch_get_main_queue(), ^{
UIViewController *topController = [UIApplication sharedApplication].keyWindow.rootViewController;
while (topController.presentedViewController) {
topController = topController.presentedViewController;
}
PaymentViewController *vc = [[PaymentViewController alloc] initWithNibName:@"PaymentViewController" bundle:nil];
vc.transactionId = transactionId;
vc.amount = amount;
vc.completionBlock = ^(id response, NSError * error) {
completedHandler(response, error);
};
[topController presentViewController:vc animated:YES completion:nil];
});
}
6.1. Tích hợp đăng ký đăng nhập

Khi một Tini App cần lấy thông tin tài khoản đang đăng nhập từ Super App, TiniAppSDK sẽ gọi tới hàm delegate getUserInfoWithCompletedHandler

Bạn có thể cài đặt delegate này như sau

- (void)getUserInfoWithCompletedHandler:(void (NS_NOESCAPE ^ _Nonnull)(TiniUser* _Nullable, NSError * _Nullable))completedHandler {
TiniUser *user = [[TiniUser alloc] initWithId:@"1234" name:@"Test user" email:@"test@gmail.com" phoneNumber:@"0123456789"];
completedHandler(user, nil);
}
6.2. Tích hợp thanh toán

Khi một Tini App cần thanh toán một đơn hàng, TiniAppSDK sẽ gọi tới hàm delegate openPaymentWithTransactionId:amount:completeHandler

Bạn có thể implement delegate này như sau.

- (void)openPaymentWithTransactionId:(NSString * _Nonnull)transactionId amount:(double)amount completedHandler:(void (^ _Nonnull)(NSDictionary<NSString *,id> * _Nullable, NSError * _Nullable))completedHandler {
dispatch_async(dispatch_get_main_queue(), ^{
UIViewController *topController = [UIApplication sharedApplication].keyWindow.rootViewController;
while (topController.presentedViewController) {
topController = topController.presentedViewController;
}
PaymentViewController *vc = [[PaymentViewController alloc] initWithNibName:@"PaymentViewController" bundle:nil];
vc.transactionId = transactionId;
vc.amount = amount;
vc.completionBlock = ^(id response, NSError * error) {
// Trường hợp thanh toán thành công
// và thực hiện thông báo lại cho TiniApp SDK thì thực hiện đoạn code sau:
completedHandler(response, error);

// Trường hợp thanh toán thất bại
// và thực hiện thông báo lại cho TiniApp SDK thì thực hiện đoạn code sau:
self.completedHandler(nil, [NSError errorWithDomain:@"TINI_SDK" code:400 userInfo:@{NSLocalizedDescriptionKey: @"{\"action\":\"goto_home\",\"msg_err\":\"Something's wrong\"}"}]);
};
[topController presentViewController:vc animated:YES completion:nil];

});
}

Ở màn hình thanh toán trên Super App của mình, sau khi thanh toán thành công, bạn cần gọi tới hàm completeHandler để báo cho TiniAppSDK biết rằng giao dịch đã được thực hiện thành công.

6.3. Hàm gọi khi đóng toàn bộ Tini App

Sau khi toàn bộ Tini App được đóng, TiniAppSDK sẽ gọi tới hàm delegate closeAppWithCompletedHandler

- (void)closeAppWithCompletedHandler:(void (NS_NOESCAPE ^)(void))completedHandler {
dispatch_async(dispatch_get_main_queue(), ^{
UIViewController *topController = [UIApplication sharedApplication].keyWindow.rootViewController;
while (topController.presentedViewController) {
topController = topController.presentedViewController;
}
[topController dismissViewControllerAnimated:YES completion:nil];
});
}

Đoạn code trên để tham khảo cách đóng TiniApp đang được mở.

Ứng dụng tích hợp mẫu

Bạn có thể xem một ứng dụng IOS mẫu đã được tích hợp tại địa chỉ Link

  • Download Example, mở terminator và cd tới folder Example, chạy pod install
cd Example
pod install
  • Mở file ExampleSDK.xcworkspace, bấm build và chạy thử trên simulator

API Interface

1. TiniAppSDK

Methoddescription
openMiniApp()Mở 1 tiniapp bất kì
config()Cấu hình cho TiniAppSDK

2. TiniAppSDK Delegate

Methoddescription
getUserInfoWithCompletedHandlerDelegate để lấy thông tin của users từ Super App
openPaymentWithTransactionId:amount:completeHandlerDelegate để mở màn hình thanh toán của Super App
closeAppWithCompletedHandlerDelegate để tắt Tini App và quay trở về Super App

3. TiniAppViewController

PropertiesTypedescription
appIdStringId của tiniapp
pagePathStringĐường dẫn tới page của tiniapp
paramsDictionaryParams cần truyền thêm cho tiniapp nếu cần