# 示例代码
## Android

原生集成应用协议组件有两种功能，一是在飞书 App 启动时，唤起自定义 sso 登录页；二是通过工作台访问应用时，跳转到自定义的应用页面。

### SSO 登录页

```
@NativeAppExtensionImpl
public class NativeAppExtension implements INativeAppExtension, INativeAppPageRouter {
    private static final String TAG = "NativeAppExtension";
    @Override
    public void init() {
    }
    @Override
    public void destroy() {
    }
    @Override
    public String getAppId() {
        return "cli_a56503ebdeaf900b";
    }
    @Override
    public void pageRoute(Context context, String linkUrl) {
        Log.i(TAG, "pageRoute linkUrl is " + linkUrl);
        // 跳转至完整自定义的原生登录Activity
        Intent intent = new Intent(context, XXXLoginActivity.class);
        intent.putExtra(LoginActivity.EXTRA_URL, linkUrl);
        context.startActivity(intent);
    }
}
```

### 原生集成应用首页

1. 参考[原生集成应用身份申请指南](https://open.larkoffice.com/document/uAjLw4CM/ukzMukzMukzM/native-integration/open-scene-introduction/protocol-components/native-integrated-application/nati) 申请应用，获取 app_id，如 cli_abcde1234567890
1. 实现 `INativeAppExtension` 及`INativeAppLauncher`协议
```
 /**
*  @author  : Feishu Sample
*/
public class CustomNativeApp implements INativeAppExtension, INativeAppLauncher {
    String tag() {
        return "";
    }
    @Override
    public void init() {
        Log.i(tag(), "init");
    }
    @Override
    public void destroy() {
        Log.i(tag(), "init");
    }
    @Override
    public void launchNativeApp(Context context, String linkUrl) {
        Log.i(tag(), "launchNativeApp");
        Toast.show(context, OPEN_API_TEST + "-" + context.getString(R.string.native_app_launcher_launch_toast));
        Intent intent = new Intent(context, NativeAppActivity.class);
        if (!(context instanceof Activity)) {
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        }
        intent.putExtra(NativeAppFragment.EXTRA_APP_ID, getAppId());
        context.startActivity(intent);
    }
}

```

## iOS

原生集成应用协议组件有两种功能，一是在飞书 App 启动时，唤起自定义 sso 登录页；二是通过工作台访问应用时，跳转到自定义的应用页面。

### SSO登录页

1. 自定义登录页面，其中包含完整的登录流程控制

```javascript 
import UIKit
class MyPassportNavigationViewController: UINavigationController {
    init() {
        let rootVC = PassportViewController()         
        super.init(rootViewController: rootVC)     
    }
}
class MyPassportViewController {
    let loginButton = UIButton()
    let userNameField = UITextField()
    let passwordField = UITextField()

override func viewDidLoad() {
        super.viewDidLoad()
        view.addSubView(loginButton)
        view.addSubView(userNameField)
        view.addSubView(passwordField)
        /* set style */        

loginButton.addTarget(self, action: #selector(onLoginButtonClicked), for: .touchUpInside)
    }
}
extension MyPassportViewController {
    func onLoginButtonClicked() {
        /* login and go to the next page with LKAppLinkExternal */
    }
}
```

2.  实现原生集成应用组件协议，打开飞书 App 时跳转到自定义的登录页 `MyPassportNavigationViewController`。其中`app_id`需要联系技术顾问获取。
```javascript 
import Foundation
import LKNativeAppExtensionExternal
@objc
public class MyPassportPageRoute: NSObject, KANativeAppExtensionProtocol {
        public func appId() -> String {
            return /* 技术顾问处获取的 app id */
        }

public func pageRoute(_ link: URL!, from: UIViewController!) {
             let nav = MyPassportNavigationViewController()
             nav.modalPresentationStyle = .fullScreen
             DispatchQueue.main.async {
                 from.present(nav, animated: true)
             }
        }
  }
```
3. 在 Object-C(.m) 文件代码中注册`MyPassportPageRoute`

方式一：直接在 OC 代码中注册
```javascript 
@import LKKABridge; // 引入 KAAPI_REGISTER 宏
@import LKNativeAppExtensionExternal;
#import <LKNativeAppExtensionExternalIMP/LKNativeAppExtensionExternalIMP-Swift.h> // 引入自定义的实现 MyNativeApp
#import "ka_auto_generated.h" // 引入 getChannel() 方法
@interface NativeAppRegistry: NSObject
@end
@implementation NativeAppRegistry
+(void)load {
    [KAAPI_REGISTER registerWithNativeApp:^id<KANativeAppExtensionProtocol> {
        return [[MyPassportPageRoute alloc] init];
    } cache:YES];
}
@end

```
方式二：在 OC 中调用 swift 代码注册
- .swift 文件
```javascript 
@objcMembers
public class MyNativeAppLoader: NSObject {
    // 注册方法
    @objc public class func swiftLoad(channel: String) {
        let api = KAAPI(channel: channel)
        api.register(nativeApp: MyPassportPageRoute.init, cache: true)
    }
}
```
- .m 文件
```javascript 
@import LKNativeAppExtensionExternal;
#import "ka_auto_generated.h" // 引入 getChannel() 方法
// 引入 MyNativeAppLoader 所在的.swift文件
#import <LKNativeAppExtensionExternalIMP/LKNativeAppExtensionExternalIMP-Swift.h>
@interface NativeAppRegistry: NSObject
@end
@implementation NativeAppRegistry
+(void)load {
    NSString * channel = [NSString stringWithUTF8String:getChannel()];
    [MyNativeAppLoader swiftLoadWithChannel:channel];
}
@end
```

### 原生集成应用首页

1. 参考[原生集成应用身份申请指南](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/native-integration/open-scene-introduction/protocol-components/native-integrated-application/nati) 申请应用，获取 app_id，如 cli_abcde1234567890
2.  实现`OpenNativeAppProtocol`协议
```javascript 
// LKNativeAppExtensionExternalIMP.swift
import LKNativeAppExtensionExternal
import Foundation
@objc
public class MyAppRootViewController: UIViewController {
    public override func viewDidLoad() {
        super.viewDidLoad()
        /* custom page view */
    }
}
@objcMembers
public class MyNativeApp: NSObject, OpenNativeAppProtocol {
    public func setupVC(url: String) -> UIViewController {
        return MyAppRootViewController()
    }

// 返回开放平台中获取的应用 app_id
    public func getNativeAppId() -> String {
        return "cli_abcde1234567890"
    } 
    static let shared: MyNativeApp = MyNativeApp()
}
```
3. 在 Object-C(.m) 文件代码中注册`MyNativeApp`

方式一：直接在 OC 代码中注册
```javascript 
@import LKKABridge; // 引入 KAAPI_REGISTER 宏
@import LKNativeAppExtensionExternal;
#import <LKNativeAppExtensionExternalIMP/LKNativeAppExtensionExternalIMP-Swift.h> //引入自定义的实现 MyNativeApp
#import "ka_auto_generated.h" // 引入 getChannel() 方法
@interface NativeAppRegistry: NSObject
@end
@implementation NativeAppRegistry
+(void)load {
    [KAAPI_REGISTER registerWithOpenNativeApp:^id<OpenNativeAppProtocol> {
        return [[MyNativeApp alloc] init];
    } cache:YES];
}
@end

```
方式二：在 OC 中调用 swift 代码注册
- .swift 文件
```javascript 
import LKKABridge
import LKNativeAppExtensionExternal
@objcMembers
public class MyNativeAppLoader: NSObject {
    // 注册方法
    @objc public class func swiftLoad(channel: String) {
        let api = KAAPI(channel: channel)
        api.register(openNativeApp: MyNativeApp.init, cache: true)
    }
}
```
- .m 文件
```javascript 
#import "ka_auto_generated.h" // 引入 getChannel() 方法
// 引入 MyNativeAppLoader 所在的.swift文件
#import <LKNativeAppExtensionExternalIMP/LKNativeAppExtensionExternalIMP-Swift.h>
@interface NativeAppRegistry: NSObject
@end
@implementation NativeAppRegistry
+(void)load {
    NSString * channel = [NSString stringWithUTF8String:getChannel()];
    [MyNativeAppLoader swiftLoadWithChannel:channel];
}
@end
```