diff --git a/OAT.xml b/OAT.xml new file mode 100644 index 0000000..ce05d67 --- /dev/null +++ b/OAT.xml @@ -0,0 +1,47 @@ + + + + LICENSE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/README.OpenSource b/README.OpenSource new file mode 100644 index 0000000..b185667 --- /dev/null +++ b/README.OpenSource @@ -0,0 +1,11 @@ +[ + { + "Name": "react-native-douyin", + "License": "MIT License", + "License File": "https://github.com/wiseqingyang/react-native-douyin/blob/master/LICENSE", + "Version Number": "1.1.4", + "Owner" : "panjinling@huawei.com", + "Upstream URL": "https://github.com/wiseqingyang/react-native-douyin", + "Description": "Tool library for initialization, authorization and sharing of Tiktok sdk" + } +] diff --git a/README.md b/README.md index c812404..ddbd9d7 100755 --- a/README.md +++ b/README.md @@ -1,140 +1,13 @@ -# react-native-douyin-lib +# @react-native-ohos/react-native-douyin-lib -## Getting started +This project is based on [react-native-douyin@1.1.4](https://github.com/wiseqingyang/react-native-douyin/tree/v1.1.4) -`$ npm install react-native-douyin-lib --save` +## Documentation -### Mostly automatic installation +- [中文](https://gitcode.com/OpenHarmony-RN/usage-docs/blob/master/zh-cn/react-native-douyin.md) -RN > 0.59 you need do nothing +- [English](https://gitcode.com/OpenHarmony-RN/usage-docs/blob/master/en/react-native-douyin.md) -else - -`$ react-native link react-native-douyin` - -### Manual installation - - -#### iOS - -1. pod 'react-native-douyin-lib', :path => '../node_modules/react-native-douyin-lib/react-native-douyin-lib.podspec' - -2. 为了保证可以正常唤起抖音短视频,在 info 标签栏的Custom iOS Target Properties中找到 LSApplicationQueriesSchemes 如果没有点击“+”添加一个并设置 Key 为LSApplicationQueriesSchemes, Value 类型为数组,将如下配置粘贴到数组中: - - ``` -LSApplicationQueriesSchemes - -douyinliteopensdk -snssdk1128 -douyinsharesdk -douyinopensdk - - ``` - -3. 配置你的App与抖音短视频通讯的 URLScheme,即申请到的appKey - -4. 分享的图片通过相册进行跨进程共享手段,如需使用分享功能,还需要填相册访问权限,在 info 标签栏中添加 Privacy - Photo Library Usage Description,具体请参考抖音开平台。 - -5.初始化以及UIApplicationDelegate部分# -在AppDelegate中引入DouyinOpenSDKApplicationDelegate.h头文件 并在 App 启动、收到 Open URL 打开 App 时调用 SDK 进行处理 -``` -#import - -@implementation AppDelegate - - - -- (BOOL)application:(UIApplication *)application openURL:(nonnull NSURL *)url options:(nonnull NSDictionary *)options { - - if ([[DouyinOpenSDKApplicationDelegate sharedInstance] application:application openURL:url sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey] annotation:options[UIApplicationOpenURLOptionsAnnotationKey]] - ) { - return YES; - } - - return NO; -} - -- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation -{ - - if ([[DouyinOpenSDKApplicationDelegate sharedInstance] application:application openURL:url sourceApplication:sourceApplication annotation:annotation]) { - return YES; - } - - return NO; -} - -- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url -{ - if ([[DouyinOpenSDKApplicationDelegate sharedInstance] application:application openURL:url sourceApplication:nil annotation:nil]) { - return YES; - } - return NO; -} -@end -``` - - - -#### Android - -1. React Native 0.60以上会自动链接,其他请手动集成 -2. 如遇sdk下载失败,在 project 级别 build.gradle文件中添加: - - ```gradle - allprojects { - repositories { - ... - maven { url 'https://dl.bintray.com/aweme-open-sdk-team/public' } - } - } - ``` -3. 若您的应用的代码存在混淆,若在混淆的情况下存在不能吊起分享的情况,请在您的proguard文件中添加 -keep class com.bytedance.sdk.open.aweme.** - -4.请确申请信息的准确性,如包名、md5等 - - - -## Usage -```javascript -import Douyin from 'react-native-douyin-lib'; -``` - -#### init(appKey) 注册 - -App 启动后合理的地方初始化。 - -- `appKey` {String} - -#### auth(scope,state) 注册 - -- `scope` {String} 请参考抖音开放平台,如'user_info' - -- `state` {String} 目前无用 - -成功的返回: - -```ts -interface IResponse { - msg: string; - code: number; - data: { - authCode: string; - state: string; - } -} -``` - -#### shareVideo(config) 注册 -该方法目前不完善,后续完成 - -``` -interface IShareVideoConfig { - videos: string[]; // 本地路径 - isPublish: boolean; // 是否跳转到发布页 - title: string; // 标题 - shortTitle: string; // 短标题 -} -``` -| +## License +This library is licensed under [The MIT License (MIT)](https://github.com/wiseqingyang/react-native-douyin/blob/master/LICENSE) diff --git a/android/README.md b/android/README.md deleted file mode 100755 index ac2fbda..0000000 --- a/android/README.md +++ /dev/null @@ -1,14 +0,0 @@ -README -====== - -If you want to publish the lib as a maven dependency, follow these steps before publishing a new version to npm: - -1. Be sure to have the Android [SDK](https://developer.android.com/studio/index.html) and [NDK](https://developer.android.com/ndk/guides/index.html) installed -2. Be sure to have a `local.properties` file in this folder that points to the Android SDK and NDK -``` -ndk.dir=/Users/{username}/Library/Android/sdk/ndk-bundle -sdk.dir=/Users/{username}/Library/Android/sdk -``` -3. Delete the `maven` folder -4. Run `./gradlew installArchives` -5. Verify that latest set of generated files is in the maven folder with the correct version number diff --git a/android/build.gradle b/android/build.gradle deleted file mode 100755 index b5159ad..0000000 --- a/android/build.gradle +++ /dev/null @@ -1,33 +0,0 @@ -apply plugin: 'com.android.library' - -def safeExtGet(prop, fallback) { - rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback -} - -android { - compileSdkVersion safeExtGet('compileSdkVersion', 23) - buildToolsVersion safeExtGet('buildToolsVersion', '23.0.1') - - defaultConfig { - minSdkVersion safeExtGet('minSdkVersion', 16) - targetSdkVersion safeExtGet('targetSdkVersion', 22) - versionCode 1 - versionName "1.0" - ndk { - abiFilters "armeabi-v7a", "x86" - } - } -} - -repositories { - jcenter() - maven { url "$projectDir/../../react-native/android" } - maven { url 'https://artifact.bytedance.com/repository/AwemeOpenSDK' } -} - -dependencies { - api 'com.facebook.react:react-native:+' - implementation 'com.bytedance.ies.ugc.aweme:opensdk-china-external:0.2.0.2' - implementation 'com.bytedance.ies.ugc.aweme:opensdk-common:0.2.0.2' - -} diff --git a/android/src/main/AndroidManifest.xml b/android/src/main/AndroidManifest.xml deleted file mode 100755 index b3a3487..0000000 --- a/android/src/main/AndroidManifest.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/android/src/main/java/com/ainuo/douyin/DouyinCallbackActivity.java b/android/src/main/java/com/ainuo/douyin/DouyinCallbackActivity.java deleted file mode 100755 index 43cc040..0000000 --- a/android/src/main/java/com/ainuo/douyin/DouyinCallbackActivity.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.ainuo.douyin; - -import android.app.Activity; -import android.content.Intent; -import android.os.Bundle; - -import androidx.annotation.Nullable; - - -public final class DouyinCallbackActivity extends Activity { - @Override - protected void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - handleIntent(getIntent()); - } - - @Override - protected void onNewIntent(Intent intent) { - super.onNewIntent(intent); - setIntent(intent); - handleIntent(intent); - } - - private void handleIntent(Intent intent) { - DouyinReceiver.sendWechatResp(this, intent); - finish(); - } -} \ No newline at end of file diff --git a/android/src/main/java/com/ainuo/douyin/DouyinModule.java b/android/src/main/java/com/ainuo/douyin/DouyinModule.java deleted file mode 100755 index 68d41be..0000000 --- a/android/src/main/java/com/ainuo/douyin/DouyinModule.java +++ /dev/null @@ -1,246 +0,0 @@ -package com.ainuo.douyin; - -import android.content.Intent; -import android.net.Uri; -import android.os.StrictMode; -import android.util.Log; - -import com.bytedance.sdk.open.aweme.CommonConstants; -import com.bytedance.sdk.open.aweme.authorize.model.Authorization; -import com.bytedance.sdk.open.aweme.base.ImageObject; -import com.bytedance.sdk.open.aweme.base.MediaContent; -import com.bytedance.sdk.open.aweme.base.ShareParam; -import com.bytedance.sdk.open.aweme.base.TitleObject; -import com.bytedance.sdk.open.aweme.base.VideoObject; -import com.bytedance.sdk.open.aweme.common.handler.IApiEventHandler; -import com.bytedance.sdk.open.aweme.common.model.BaseReq; -import com.bytedance.sdk.open.aweme.common.model.BaseResp; -import com.bytedance.sdk.open.aweme.init.DouYinOpenSDKConfig; -import com.bytedance.sdk.open.aweme.share.Share; -import com.bytedance.sdk.open.douyin.DouYinOpenApiFactory; -import com.bytedance.sdk.open.douyin.api.DouYinOpenApi; -import com.bytedance.sdk.open.douyin.model.OpenRecord; -import com.facebook.react.bridge.Arguments; -import com.facebook.react.bridge.LifecycleEventListener; -import com.facebook.react.bridge.Promise; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.bridge.ReactContextBaseJavaModule; -import com.facebook.react.bridge.ReactMethod; -import com.facebook.react.bridge.ReadableArray; -import com.facebook.react.bridge.ReadableMap; -import com.facebook.react.bridge.WritableMap; - -import java.io.File; -import java.util.ArrayList; - -public class DouyinModule extends ReactContextBaseJavaModule implements LifecycleEventListener { - - public ReactApplicationContext mContext; - public static DouYinOpenApi douyinOpenApi; - private String callerLocalEntry = "com.ainuo.douyin.DouyinCallbackActivity"; - public static Intent callbackInit; - public Promise promise; - - - public DouyinModule(ReactApplicationContext reactContext) { - super(reactContext); - mContext = reactContext; - - reactContext.addLifecycleEventListener(this); - } - - - @Override - public String getName() { - return "DouYinModule"; - } - - public String getFileUri(String filePath) { - - File file = new File(filePath); - String authority = mContext.getPackageName() + ".douyinFileProvider"; - Uri gpxContentUri; - try { - gpxContentUri = FileProviderAdapter.getUriForFile(mContext, authority, file); - } catch (IllegalArgumentException e) { - StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder(); - StrictMode.setVmPolicy(builder.build()); - gpxContentUri = Uri.fromFile(file); - } - // 授权给抖音访问路径,这里填抖音包名 - mContext.grantUriPermission("com.ss.android.ugc.aweme", - gpxContentUri, Intent.FLAG_GRANT_READ_URI_PERMISSION); - return gpxContentUri.toString(); // contentUri.toString() 即是以"content://"开头的用于共享的路径 - } - - - @ReactMethod - public void init(String appId) { - DouYinOpenApiFactory.initConfig( - new DouYinOpenSDKConfig.Builder() - .context(mContext) - .clientKey(appId) - .build() - ); - douyinOpenApi = DouYinOpenApiFactory.create(getCurrentActivity()); - - DouyinReceiver.registerReceiver(mContext, douyinReceiver); - } - - private DouyinReceiver douyinReceiver = new DouyinReceiver() { - @Override - public void handleIntent(Intent intent) { - if (douyinOpenApi != null) { - douyinOpenApi.handleIntent(intent, iApiEventHandler); - } - } - }; - - private IApiEventHandler iApiEventHandler = new IApiEventHandler() { - @Override - public void onReq(BaseReq req) { - - } - - @Override - public void onResp(BaseResp resp) { - WritableMap map = Arguments.createMap(); - Log.d("douyin__", String.valueOf(resp.errorCode)); - Log.d("douyin__", String.valueOf(resp.errorMsg)); - Log.d("douyin__", String.valueOf(resp.getType())); - if (resp.getType() == CommonConstants.ModeType.SHARE_CONTENT_TO_TT_RESP) { - map.putInt("code", resp.isSuccess() ? 0 : resp.errorCode); - map.putString("msg", resp.errorMsg); - promise.resolve(map); - } - - if (resp.getType() == CommonConstants.ModeType.SEND_AUTH_RESPONSE) { - Authorization.Response response = (Authorization.Response) resp; - map.putInt("code", resp.isSuccess() ? 0 : response.errorCode); - map.putString("msg", resp.errorMsg); - if (resp.isSuccess()) { - WritableMap data = Arguments.createMap(); - data.putString("authCode", response.authCode); - data.putString("state", response.state); - map.putMap("data", map); - } - promise.resolve(map); - } - } - - @Override - public void onErrorIntent(Intent intent) { - - } - }; - - @ReactMethod - public void isAppInstalled(Promise promise) { - if (douyinOpenApi == null) { - WritableMap map = Arguments.createMap(); - map.putInt("code", -99); - map.putString("msg", "sdk 未初始化"); - promise.resolve(map); - return; - } - WritableMap map = Arguments.createMap(); - map.putInt("code", 0); - map.putBoolean("data", douyinOpenApi.isAppInstalled()); - promise.resolve(map); - } - - ; - - @ReactMethod - public void shareVideo(ReadableMap config, Promise promise) { - - if (douyinOpenApi == null) { - WritableMap map = Arguments.createMap(); - map.putInt("code", -99); - map.putString("msg", "sdk 未初始化"); - promise.resolve(map); - return; - } - - ReadableArray fileNames = config.getArray("videos"); - Boolean isPublish = config.getBoolean("isPublish"); - String shortTitle = config.getString("shortTitle"); - String title = config.getString("title"); - - if (douyinOpenApi.isShareSupportFileProvider() && - android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) { - - this.promise = promise; - - ArrayList videos = new ArrayList<>(); - for (int i = 0; i < fileNames.size(); i++) { - String path = getFileUri(fileNames.getString(i)); - videos.add(path); - } - - Share.Request request = new Share.Request(); - VideoObject videoObject = new VideoObject(); - videoObject.mVideoPaths = videos; // 该地方路径可以传FileProvider格式的路径 - MediaContent content = new MediaContent(); - content.mMediaObject = videoObject; - request.mMediaContent = content; - //指定当前类名 - request.callerLocalEntry = callerLocalEntry; - - request.newShare = true; - ShareParam shareParam = new ShareParam(); - request.shareParam = shareParam; - - TitleObject titleObject = new TitleObject(); - shareParam.titleObject = titleObject; - titleObject.shortTitle = shortTitle; // 抖音30.0.0版本开始支持该字段 - titleObject.title = title; - - if (douyinOpenApi.isAppSupportShareToPublish() && isPublish) { - request.shareToPublish = true; - } - - douyinOpenApi.share(request); - } else { - WritableMap map = Arguments.createMap(); - map.putInt("code", -98); - map.putString("msg", "当前版本不支持分享"); - promise.resolve(map); - } - } - - @ReactMethod - public void record(Promise promise) { - OpenRecord.Request request = new OpenRecord.Request(); - if (douyinOpenApi != null && douyinOpenApi.isSupportOpenRecordPage()) { // 判断抖音版本是否支持打开抖音拍摄页 - douyinOpenApi.openRecordPage(request); - } - } - - //授权登录 - @ReactMethod - public void auth(String scope, String state, Promise promise) { - Authorization.Request request = new Authorization.Request(); - this.promise = promise; - request.callerLocalEntry = callerLocalEntry; - request.scope = scope; - request.state = state; // 用于保持请求和回调的状态,授权请求后原样带回给第三方。 - douyinOpenApi.authorize(request); // 优先使用抖音app进行授权,如果抖音app因版本或者其他原因无法授权,则使用wap页授权 - } - - - @Override - public void onHostResume() { - - } - - @Override - public void onHostPause() { - - } - - @Override - public void onHostDestroy() { - - } -} diff --git a/android/src/main/java/com/ainuo/douyin/DouyinPackage.java b/android/src/main/java/com/ainuo/douyin/DouyinPackage.java deleted file mode 100755 index 567f1a7..0000000 --- a/android/src/main/java/com/ainuo/douyin/DouyinPackage.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.ainuo.douyin; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import com.facebook.react.ReactPackage; -import com.facebook.react.bridge.NativeModule; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.uimanager.ViewManager; -import com.facebook.react.bridge.JavaScriptModule; - -public class DouyinPackage implements ReactPackage { - @Override - public List createNativeModules(ReactApplicationContext reactContext) { - return Arrays.asList(new DouyinModule(reactContext)); - } - - @Override - public List createViewManagers(ReactApplicationContext reactContext) { - return Collections.emptyList(); - } -} diff --git a/android/src/main/java/com/ainuo/douyin/DouyinReceiver.java b/android/src/main/java/com/ainuo/douyin/DouyinReceiver.java deleted file mode 100755 index efd820a..0000000 --- a/android/src/main/java/com/ainuo/douyin/DouyinReceiver.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.ainuo.douyin; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.text.TextUtils; - -public abstract class DouyinReceiver extends BroadcastReceiver { - private static final String ACTION_DOUYIN_RESP = DouyinReceiver.class.getPackage() + ".action.DOUYIN_RESP"; - - private static final String KEY_DOUYIN_RESP = "douyin_resp"; - - @Override - public void onReceive(Context context, Intent intent) { - if (TextUtils.equals(ACTION_DOUYIN_RESP, intent.getAction())) { - Intent resp = intent.getParcelableExtra(KEY_DOUYIN_RESP); - handleIntent(resp); - } - } - - public abstract void handleIntent(Intent intent); - - public static void registerReceiver(Context context, DouyinReceiver receiver) { - IntentFilter intentFilter = new IntentFilter(); - intentFilter.addAction(ACTION_DOUYIN_RESP); - context.registerReceiver(receiver, intentFilter); - } - - public static void unregisterReceiver(Context context, DouyinReceiver receiver) { - context.unregisterReceiver(receiver); - } - - public static void sendWechatResp(Context context, Intent resp) { - Intent intent = new Intent(); - intent.setAction(ACTION_DOUYIN_RESP); - intent.putExtra(KEY_DOUYIN_RESP, resp); - intent.setPackage(context.getPackageName()); - context.sendBroadcast(intent); - } -} \ No newline at end of file diff --git a/android/src/main/java/com/ainuo/douyin/FileProviderAdapter.java b/android/src/main/java/com/ainuo/douyin/FileProviderAdapter.java deleted file mode 100755 index 5c33541..0000000 --- a/android/src/main/java/com/ainuo/douyin/FileProviderAdapter.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.ainuo.douyin; -import androidx.core.content.FileProvider; - -public class FileProviderAdapter extends FileProvider { -} diff --git a/android/src/main/res/xml/file_provider_paths.xml b/android/src/main/res/xml/file_provider_paths.xml deleted file mode 100755 index fe05cd3..0000000 --- a/android/src/main/res/xml/file_provider_paths.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/harmony/douyin/.gitignore b/harmony/douyin/.gitignore new file mode 100644 index 0000000..e2713a2 --- /dev/null +++ b/harmony/douyin/.gitignore @@ -0,0 +1,6 @@ +/node_modules +/oh_modules +/.preview +/build +/.cxx +/.test \ No newline at end of file diff --git a/harmony/douyin/.ohpmrc b/harmony/douyin/.ohpmrc new file mode 100644 index 0000000..e6008b2 --- /dev/null +++ b/harmony/douyin/.ohpmrc @@ -0,0 +1,13 @@ +publish_registry=https://ohpm.byted.org/repos/ohpm +registry=https://ohpm.byted.org/repos/ohpm/,http://artifact.bytedance.com/repository/byted-ohpm/ +# 开启依赖名称校验,本地依赖名称与其对应的包名是否一致,若不一致会导致命令执行失败 +enforce_dependency_key=true +# 是否开启默认的冲突处理机制 +resolve_conflict=true +# 是否安装工程所有模块的依赖 +install_all=true +# 启用跨进程锁,ohpm不支持在同一个工程下并行运行多个ohpm 命令,保证串行执行 +enable_cross_process_lock=true +# 开启依赖扫描功能,在执行ohpm publish命令时,会检查三方依赖是否都声明在dependencies中 +ensure_dependency_include=true +strict_ssl=false \ No newline at end of file diff --git a/harmony/douyin/BuildProfile.ets b/harmony/douyin/BuildProfile.ets new file mode 100644 index 0000000..5078e0d --- /dev/null +++ b/harmony/douyin/BuildProfile.ets @@ -0,0 +1,17 @@ +/** + * Use these variables when you tailor your ArkTS code. They must be of the const type. + */ +export const HAR_VERSION = '1.2.0-rc.1'; +export const BUILD_MODE_NAME = 'debug'; +export const DEBUG = true; +export const TARGET_NAME = 'default'; + +/** + * BuildProfile Class is used only for compatibility purposes. + */ +export default class BuildProfile { + static readonly HAR_VERSION = HAR_VERSION; + static readonly BUILD_MODE_NAME = BUILD_MODE_NAME; + static readonly DEBUG = DEBUG; + static readonly TARGET_NAME = TARGET_NAME; +} \ No newline at end of file diff --git a/harmony/douyin/build-profile.json5 b/harmony/douyin/build-profile.json5 new file mode 100644 index 0000000..4d61187 --- /dev/null +++ b/harmony/douyin/build-profile.json5 @@ -0,0 +1,28 @@ +{ + "apiType": "stageMode", + "buildOption": { + }, + "buildOptionSet": [ + { + "name": "release", + "arkOptions": { + "obfuscation": { + "ruleOptions": { + "enable": false, + "files": [ + "./obfuscation-rules.txt" + ] + } + } + } + }, + ], + "targets": [ + { + "name": "default" + }, + { + "name": "ohosTest", + } + ] +} \ No newline at end of file diff --git a/harmony/douyin/hvigorfile.ts b/harmony/douyin/hvigorfile.ts new file mode 100644 index 0000000..4218707 --- /dev/null +++ b/harmony/douyin/hvigorfile.ts @@ -0,0 +1,6 @@ +import { harTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: harTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/harmony/douyin/index.ets b/harmony/douyin/index.ets new file mode 100644 index 0000000..e156195 --- /dev/null +++ b/harmony/douyin/index.ets @@ -0,0 +1,26 @@ +/* + * MIT License + * + * Copyright (C) 2024 Huawei Device Co., Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +import { RNDouYinPackage } from './src/main/ets/RNDouYinPackage'; +export default RNDouYinPackage; +export * from "./ts"; \ No newline at end of file diff --git a/harmony/douyin/obfuscation-rules.txt b/harmony/douyin/obfuscation-rules.txt new file mode 100644 index 0000000..272efb6 --- /dev/null +++ b/harmony/douyin/obfuscation-rules.txt @@ -0,0 +1,23 @@ +# Define project specific obfuscation rules here. +# You can include the obfuscation configuration files in the current module's build-profile.json5. +# +# For more details, see +# https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/source-obfuscation-V5 + +# Obfuscation options: +# -disable-obfuscation: disable all obfuscations +# -enable-property-obfuscation: obfuscate the property names +# -enable-toplevel-obfuscation: obfuscate the names in the global scope +# -compact: remove unnecessary blank spaces and all line feeds +# -remove-log: remove all console.* statements +# -print-namecache: print the name cache that contains the mapping from the old names to new names +# -apply-namecache: reuse the given cache file + +# Keep options: +# -keep-property-name: specifies property names that you want to keep +# -keep-global-name: specifies names that you want to keep in the global scope + +-enable-property-obfuscation +-enable-toplevel-obfuscation +-enable-filename-obfuscation +-enable-export-obfuscation \ No newline at end of file diff --git a/harmony/douyin/oh-package.json5 b/harmony/douyin/oh-package.json5 new file mode 100644 index 0000000..41a8fff --- /dev/null +++ b/harmony/douyin/oh-package.json5 @@ -0,0 +1,14 @@ +{ + "name": "@react-native-ohos/react-native-douyin-lib", + "version": "1.1.4", + "description": "Keep the screen from going to sleep", + "main": "index.ets", + "author": "", + "license": "Apache-2.0", + "dependencies": { + "@rnoh/react-native-openharmony": "file:../libs/react_native_openharmony-5.0.0.490.har", + "@douyin/opensdk-common-external": "0.0.5" + } +} + + diff --git a/harmony/douyin/src/main/cpp/CMakeLists.txt b/harmony/douyin/src/main/cpp/CMakeLists.txt new file mode 100644 index 0000000..7b5d01e --- /dev/null +++ b/harmony/douyin/src/main/cpp/CMakeLists.txt @@ -0,0 +1,9 @@ +cmake_minimum_required(VERSION 3.13) +set(CMAKE_VERBOSE_MAKEFILE on) + +set(rnoh_douyin_generated_dir "${CMAKE_CURRENT_SOURCE_DIR}/generated") +file(GLOB_RECURSE rnoh_douyin_generated_SRC "${rnoh_douyin_generated_dir}/*.cpp") +file(GLOB rnoh_douyin_SRC CONFIGURE_DEPENDS *.cpp) +add_library(rnoh_douyin SHARED ${rnoh_douyin_SRC} ${rnoh_douyin_generated_SRC}) +target_include_directories(rnoh_douyin PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${rnoh_douyin_generated_dir}) +target_link_libraries(rnoh_douyin PUBLIC rnoh) \ No newline at end of file diff --git a/harmony/douyin/src/main/cpp/generated/DouYinNativeModule.cpp b/harmony/douyin/src/main/cpp/generated/DouYinNativeModule.cpp new file mode 100644 index 0000000..75a8419 --- /dev/null +++ b/harmony/douyin/src/main/cpp/generated/DouYinNativeModule.cpp @@ -0,0 +1,19 @@ +/** + * This code was generated by "react-native codegen-lib-harmony" + */ + +#include "DouYinNativeModule.h" + +namespace rnoh { +using namespace facebook; + +DouYinNativeModule::DouYinNativeModule(const ArkTSTurboModule::Context ctx, const std::string name) : ArkTSTurboModule(ctx, name) { + methodMap_ = { + ARK_METHOD_METADATA(init, 1), + ARK_ASYNC_METHOD_METADATA(auth, 3), + ARK_ASYNC_METHOD_METADATA(shareVideo, 1), + ARK_METHOD_METADATA(isAppInstalled, 0), + }; +} + +} // namespace rnoh diff --git a/harmony/douyin/src/main/cpp/generated/DouYinNativeModule.h b/harmony/douyin/src/main/cpp/generated/DouYinNativeModule.h new file mode 100644 index 0000000..c2c3aee --- /dev/null +++ b/harmony/douyin/src/main/cpp/generated/DouYinNativeModule.h @@ -0,0 +1,16 @@ +/** + * This code was generated by "react-native codegen-lib-harmony" + */ + +#pragma once + +#include "RNOH/ArkTSTurboModule.h" + +namespace rnoh { + +class JSI_EXPORT DouYinNativeModule : public ArkTSTurboModule { + public: + DouYinNativeModule(const ArkTSTurboModule::Context ctx, const std::string name); +}; + +} // namespace rnoh diff --git a/harmony/douyin/src/main/cpp/generated/DouYinPackage.h b/harmony/douyin/src/main/cpp/generated/DouYinPackage.h new file mode 100644 index 0000000..be5c626 --- /dev/null +++ b/harmony/douyin/src/main/cpp/generated/DouYinPackage.h @@ -0,0 +1,76 @@ +/** + * This code was generated by "react-native codegen-harmony" + * + * Do not edit this file as changes may cause incorrect behavior and will be + * lost once the code is regenerated. + * + * @generatorVersion: 1 + */ + +#pragma once + +#include "RNOH/Package.h" +#include "RNOH/ArkTSTurboModule.h" +#include "DouYinNativeModule.h" + +namespace rnoh { + +class DouYinPackageTurboModuleFactoryDelegate : public TurboModuleFactoryDelegate { + public: + SharedTurboModule createTurboModule(Context ctx, const std::string &name) const override { + if (name == "DouYinModule") { + return std::make_shared(ctx, name); + } + return nullptr; + }; +}; + +class DouYinPackageEventEmitRequestHandler : public EventEmitRequestHandler { + public: + void handleEvent(Context const &ctx) override { + auto eventEmitter = ctx.shadowViewRegistry->getEventEmitter(ctx.tag); + auto componentName = ctx.shadowViewRegistry->getComponentName(ctx.tag); + + if (eventEmitter == nullptr) { + return; + } + + std::vector supportedComponentNames = { + }; + + std::vector supportedEventNames = { + }; + + if (std::find(supportedComponentNames.begin(), supportedComponentNames.end(), componentName) != supportedComponentNames.end() && + std::find(supportedEventNames.begin(), supportedEventNames.end(), ctx.eventName) != supportedEventNames.end()) { + eventEmitter->dispatchEvent(ctx.eventName, ArkJS(ctx.env).getDynamic(ctx.payload)); + } + } +}; + +class DouYinPackage : public Package { + public: + DouYinPackage(Package::Context ctx) : Package(ctx){}; + + std::unique_ptr createTurboModuleFactoryDelegate() override { + return std::make_unique(); + } + + std::vector createComponentDescriptorProviders() override { + return { + }; + } + + ComponentJSIBinderByString createComponentJSIBinderByName() override { + return { + }; + }; + + EventEmitRequestHandlers createEventEmitRequestHandlers() override { + return { + std::make_shared(), + }; + } +}; + +} // namespace rnoh diff --git a/harmony/douyin/src/main/ets/RNDouYinPackage.ets b/harmony/douyin/src/main/ets/RNDouYinPackage.ets new file mode 100644 index 0000000..9a45406 --- /dev/null +++ b/harmony/douyin/src/main/ets/RNDouYinPackage.ets @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved + * Use of this source code is governed by a MIT license that can be + * found in the LICENSE file. + */ + + +import { TurboModulesFactory } from '@rnoh/react-native-openharmony/ts'; +import type { TurboModule, TurboModuleContext } from '@rnoh/react-native-openharmony/ts'; +import { TM } from './generated/ts' +import { RNDouYinTurboModule } from './RNDouYinTurboModule'; +import { RNOHPackage } from '@rnoh/react-native-openharmony'; + +class RNDouYinTurboModuleFactory extends TurboModulesFactory { + createTurboModule(name: string): TurboModule | null { + if (this.hasTurboModule(name)) { + return new RNDouYinTurboModule(this.ctx); + } + return null; + } + + hasTurboModule(name: string): boolean { + return name === TM.DouYinNativeModule.NAME; + } +} + +export class RNDouYinPackage extends RNOHPackage { + createTurboModulesFactory(ctx: TurboModuleContext): TurboModulesFactory { + return new RNDouYinTurboModuleFactory(ctx); + } +} \ No newline at end of file diff --git a/harmony/douyin/src/main/ets/RNDouYinTurboModule.ets b/harmony/douyin/src/main/ets/RNDouYinTurboModule.ets new file mode 100644 index 0000000..a623a2f --- /dev/null +++ b/harmony/douyin/src/main/ets/RNDouYinTurboModule.ets @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2026 Huawei Device Co., Ltd. All rights reserved + * Use of this source code is governed by a MIT license that can be + * found in the LICENSE file. + */ + +import { TurboModule, UITurboModuleContext } from '@rnoh/react-native-openharmony/ts'; +import { TM } from './generated/ts'; +import { + DouYinOpenConfigBuilder, + DouYinOpenListener, + douYinOpenSDK, + MixObject, + OpenAuthRequest, + OpenAuthResponse, + OpenShareRequest, + OpenShareResponse, + OpenTitleObject, + SupportApiName +} from '@douyin/opensdk-common-external'; +import { bundleManager, common, Want } from '@kit.AbilityKit'; +import { fileUri } from '@kit.CoreFileKit'; + +interface ShareConfig { + videos: string[]; + isPublish?: boolean; + title?: string; + shortTitle?: string; +} + +export class RNDouYinTurboModule extends TurboModule implements TM.DouYinNativeModule.Spec { + private appLink: string = ''; + + constructor(ctx: UITurboModuleContext) { + super(ctx); + } + + init(appKey: string): void { + let apiParam = new DouYinOpenConfigBuilder(appKey) + .setDebug(true) + .build(); + douYinOpenSDK.init(apiParam) + } + + auth(scope: string, state: string, appLink: string): Promise { + this.appLink = appLink; + return new Promise((resolve, reject) => { + let listener: DouYinOpenListener = { + onSuccess: (response: OpenAuthResponse, authCode: string, grantedPermissions: string) => { + let result: ESObject = { code: response.isSuccess() ? 0 : response.errorCode, msg: response.errorMsg } + resolve(JSON.stringify(result)) + }, + onError: (response: OpenAuthResponse, errCode: number, errMsg: string) => { + let result: ESObject = { code: errCode, msg: errMsg } + reject(JSON.stringify(result)); + } + } + let authRequest: OpenAuthRequest = new OpenAuthRequest(); + authRequest.scope = scope; + authRequest.state = state; + authRequest.callerLocalEntry = "EntryAbility" + authRequest.redirectUri = appLink + douYinOpenSDK.createDouYinOpenApi()?.authorize(getContext() as common.UIAbilityContext, authRequest, listener) + }); + } + + shareVideo(shareConfig: ShareConfig): Promise { + return new Promise((resolve, reject) => { + let listener: DouYinOpenListener = { + onSuccess: (response: OpenShareResponse) => { + let result: ESObject = { code: response.isSuccess() ? 0 : response.errorCode, msg: response.errorMsg } + resolve(JSON.stringify(result)) + }, + onError: (response: OpenShareResponse, errCode: number, errMsg: string) => { + let result: ESObject = { code: errCode, msg: errMsg } + reject(JSON.stringify(result)); + } + } + const request: OpenShareRequest = this.buildShareRequest(shareConfig.title, shareConfig.shortTitle) + let douYinOpenApi = douYinOpenSDK.createDouYinOpenApi() + if (douYinOpenApi?.isSupportApi(SupportApiName.SUPPORT_MIX) == true) { + let mixObject = new MixObject() + let videos = shareConfig.videos + if (videos && videos.length > 0) { + for (let i = 0; i < videos.length; i++) { + let uri = fileUri.getUriFromPath(videos[i]) + mixObject.uriList.push(uri) + } + } + request.mediaObject = mixObject + } + douYinOpenSDK.createDouYinOpenApi()?.share(getContext() as common.UIAbilityContext, request, listener) + }); + } + + isAppInstalled(): boolean { + try { + let link = 'snssdk1128://aweme/detail'; + let canOpen = bundleManager.canOpenLink(link); + return canOpen; + } catch (err) { + let message = (err as BusinessError).message; + console.info('canOpenLink failed:'+JSON.stringify(message)) + return false; + } + } + + private buildShareRequest(title: string | undefined, shortTitle: string | undefined): OpenShareRequest { + let request = new OpenShareRequest() + request.state = "state" + request.callerLocalEntry = "EntryAbility" + request.redirectUri = this.appLink + request.titleObject = new OpenTitleObject() + if (title) { + request.titleObject.title = title + } + + if (shortTitle) { + request.titleObject.shortTitle = shortTitle + } + return request + } +} + +export function doResult(context: common.UIAbilityContext, want: Want) { + douYinOpenSDK.doResult(context, want) +} diff --git a/harmony/douyin/src/main/ets/generated/components/ts.ts b/harmony/douyin/src/main/ets/generated/components/ts.ts new file mode 100644 index 0000000..d1dae56 --- /dev/null +++ b/harmony/douyin/src/main/ets/generated/components/ts.ts @@ -0,0 +1,5 @@ + +/** + */ + +export {} diff --git a/harmony/douyin/src/main/ets/generated/index.ets b/harmony/douyin/src/main/ets/generated/index.ets new file mode 100644 index 0000000..041b7ed --- /dev/null +++ b/harmony/douyin/src/main/ets/generated/index.ets @@ -0,0 +1,5 @@ +/** + * This code was generated by "react-native codegen-lib-harmony" + */ + +export * from "./ts" diff --git a/harmony/douyin/src/main/ets/generated/ts.ts b/harmony/douyin/src/main/ets/generated/ts.ts new file mode 100644 index 0000000..4c568a8 --- /dev/null +++ b/harmony/douyin/src/main/ets/generated/ts.ts @@ -0,0 +1,6 @@ +/** + * This code was generated by "react-native codegen-lib-harmony" + */ + +export * as RNC from "./components/ts" +export * as TM from "./turboModules/ts" diff --git a/harmony/douyin/src/main/ets/generated/turboModules/DouYinNativeModule.ts b/harmony/douyin/src/main/ets/generated/turboModules/DouYinNativeModule.ts new file mode 100644 index 0000000..cd03e29 --- /dev/null +++ b/harmony/douyin/src/main/ets/generated/turboModules/DouYinNativeModule.ts @@ -0,0 +1,19 @@ +/** + * This code was generated by "react-native codegen-lib-harmony" + */ + +import { Tag } from "@rnoh/react-native-openharmony/ts" + +export namespace DouYinNativeModule { + export const NAME = 'DouYinModule' as const + + export interface Spec { + init(appKey: string): void; + + auth(scope: string, state: string, appLink: string): Promise; + + shareVideo(shareConfig: any): Promise; + + isAppInstalled(): boolean; + } +} \ No newline at end of file diff --git a/harmony/douyin/src/main/ets/generated/turboModules/ts.ts b/harmony/douyin/src/main/ets/generated/turboModules/ts.ts new file mode 100644 index 0000000..6c65c51 --- /dev/null +++ b/harmony/douyin/src/main/ets/generated/turboModules/ts.ts @@ -0,0 +1,5 @@ +/** + * This code was generated by "react-native codegen-lib-harmony" + */ + +export * from "./DouYinNativeModule" diff --git a/harmony/douyin/src/main/module.json5 b/harmony/douyin/src/main/module.json5 new file mode 100644 index 0000000..268abd4 --- /dev/null +++ b/harmony/douyin/src/main/module.json5 @@ -0,0 +1,11 @@ +{ + "module": { + "name": "douyin", + "type": "har", + "deviceTypes": [ + "default", + "tablet", + "2in1" + ] + }, +} \ No newline at end of file diff --git a/harmony/douyin/src/main/resources/base/element/color.json b/harmony/douyin/src/main/resources/base/element/color.json new file mode 100644 index 0000000..3c71296 --- /dev/null +++ b/harmony/douyin/src/main/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/harmony/douyin/src/main/resources/base/element/string.json b/harmony/douyin/src/main/resources/base/element/string.json new file mode 100644 index 0000000..e314636 --- /dev/null +++ b/harmony/douyin/src/main/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "send_intent_desc", + "value": "description" + }, + { + "name": "send_intent_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/harmony/douyin/src/main/resources/base/profile/backup_config.json b/harmony/douyin/src/main/resources/base/profile/backup_config.json new file mode 100644 index 0000000..78f40ae --- /dev/null +++ b/harmony/douyin/src/main/resources/base/profile/backup_config.json @@ -0,0 +1,3 @@ +{ + "allowToBackupRestore": true +} \ No newline at end of file diff --git a/harmony/douyin/src/main/resources/base/profile/main_pages.json b/harmony/douyin/src/main/resources/base/profile/main_pages.json new file mode 100644 index 0000000..1898d94 --- /dev/null +++ b/harmony/douyin/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "pages/Index" + ] +} diff --git a/harmony/douyin/src/main/resources/en_US/element/string.json b/harmony/douyin/src/main/resources/en_US/element/string.json new file mode 100644 index 0000000..e314636 --- /dev/null +++ b/harmony/douyin/src/main/resources/en_US/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "send_intent_desc", + "value": "description" + }, + { + "name": "send_intent_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/harmony/douyin/src/main/resources/zh_CN/element/string.json b/harmony/douyin/src/main/resources/zh_CN/element/string.json new file mode 100644 index 0000000..abf20f5 --- /dev/null +++ b/harmony/douyin/src/main/resources/zh_CN/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "模块描述" + }, + { + "name": "send_intent_desc", + "value": "description" + }, + { + "name": "send_intent_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/harmony/douyin/ts.ets b/harmony/douyin/ts.ets new file mode 100644 index 0000000..a72cf51 --- /dev/null +++ b/harmony/douyin/ts.ets @@ -0,0 +1,8 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved + * Use of this source code is governed by a MIT license that can be + * found in the LICENSE file. + */ + +export * from './src/main/ets/RNDouYinPackage'; +export * from './src/main/ets/RNDouYinTurboModule' \ No newline at end of file diff --git a/index.d.ts b/index.d.ts index 4487cfb..970f7c0 100644 --- a/index.d.ts +++ b/index.d.ts @@ -11,7 +11,7 @@ declare module "react-native-douyin-lib" { export function init(appKey: string):Promise; - export function auth(scope: string,state:string): Promise; + export function auth(scope: string,state:string,appLink:string): Promise; export function shareVideo(shareConfig: { videos: string[]; diff --git a/index.js b/index.js index 3809ed7..0229901 100755 --- a/index.js +++ b/index.js @@ -7,8 +7,8 @@ export default Douyin = { DouYinModule.init(appKey); }, - auth(scope, state) { - return DouYinModule.auth(scope, state); + auth(scope, state, appLink) { + return DouYinModule.auth(scope, state, appLink); }, shareVideo(config) { diff --git a/ios/Douyin.h b/ios/Douyin.h deleted file mode 100755 index dbd0f3d..0000000 --- a/ios/Douyin.h +++ /dev/null @@ -1,6 +0,0 @@ -#import -#import - -@interface Douyin : NSObject - -@end diff --git a/ios/Douyin.m b/ios/Douyin.m deleted file mode 100755 index 06157f8..0000000 --- a/ios/Douyin.m +++ /dev/null @@ -1,142 +0,0 @@ -#import "Douyin.h" -#import -#import "DouyinOpenSDKShare.h" -#import -#import -#import - - - -@implementation Douyin - -RCT_EXPORT_MODULE(DouYinModule) - - - - - -RCT_EXPORT_METHOD(auth:(NSString *)scope - state:(NSString *)state - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ - - DouyinOpenSDKAuthRequest *req = [[DouyinOpenSDKAuthRequest alloc] init]; - - req.permissions = [NSOrderedSet orderedSetWithObject:scope]; - // req.state=state; - - UIViewController *vc = [UIApplication sharedApplication].keyWindow.rootViewController; - - [req sendAuthRequestViewController:vc completeBlock:^(DouyinOpenSDKAuthResponse * _Nonnull resp) { - if (resp.errCode == 0) { - NSDictionary *data = @{ - @"authCode": resp.code, - @"state": resp.state - }; - resolve(@{ - @"code": [NSNumber numberWithInt:(int)resp.errCode], - @"msg": resp.errString, - @"data": data - }); - } else{ - [NSString stringWithFormat:@"Author failed code : %@, msg : %@",@(resp.errCode), resp.errString]; - reject([NSString stringWithFormat:@"%@",@(resp.errCode)],resp.errString,nil); - } - }]; - - }); -} - - -RCT_EXPORT_METHOD(init:(NSString *)appid - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ - - [[DouyinOpenSDKApplicationDelegate sharedInstance] registerAppId:appid]; - [DouyinOpenSDKApplicationDelegate sharedInstance].logDelegate =self; - }); -} - -RCT_EXPORT_METHOD(isAppInstalled:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - BOOL installed = [[DouyinOpenSDKApplicationDelegate sharedInstance] isAppInstalled]; - - NSDictionary *dic = @{ - @"code": @0, - @"data": installed ? @YES : @NO - }; - resolve(dic); -} - -RCT_EXPORT_METHOD(shareVideo:(NSDictionary*) config - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - - NSArray* filePaths = [config valueForKey:@"videos"]; - - BOOL isPublish = config[@"isPublish"]; - NSString* shortTitle = config[@"shortTitle"]; - NSString* title = config[@"title"]; - - DouyinOpenSDKShareRequest *req = [[DouyinOpenSDKShareRequest alloc] init]; - req.mediaType = DouyinOpenSDKShareMediaTypeVideo; - req.landedPageType = isPublish ? DouyinOpenSDKLandedPagePublish : DouyinOpenSDKLandedPageEdit; - req.publishStory = NO; - - req.title = [DouyinOpenSDKShareTitle new]; - req.title.text = title; - req.title.shortTitle = shortTitle; - - [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) { - if (status == PHAuthorizationStatusAuthorized) { - [[PHPhotoLibrary sharedPhotoLibrary]performChanges:^{ - NSMutableArray *assetLocalIds = [NSMutableArray new]; - for (NSString* item in filePaths) { - NSURL *url = [NSURL URLWithString:filePaths.firstObject]; // file:// - PHAssetChangeRequest *request = [PHAssetChangeRequest creationRequestForAssetFromVideoAtFileURL:url]; - NSString *localId = request.placeholderForCreatedAsset.localIdentifier; - [assetLocalIds addObject:localId]; - } - req.localIdentifiers = assetLocalIds; - } completionHandler:^(BOOL success, NSError * _Nullable error) { - if(success) { - dispatch_async(dispatch_get_main_queue(), ^{ - [req sendShareRequestWithCompleteBlock:^(DouyinOpenSDKShareResponse * _Nonnull Response) { - NSDictionary *dic = @{ - @"code": [NSNumber numberWithInt:(int)Response.errCode], - @"msg": [NSString stringWithFormat:@"%@, subCode:%ld", Response.errString, (long)Response.subErrorCode], - }; - resolve(dic); - }]; - }); - } else { - NSDictionary *dic = @{ - @"code": @-98, - @"msg": @"处理相册文件失败", - }; - resolve(dic); - } - - }]; - } else { - NSDictionary *dic = @{ - @"code": @-99, - @"msg": @"获取相册权限失败", - }; - resolve(dic); - } - }]; - - -} - -#pragma mark - DouyinOpenSDKLogDelegate Delegate -- (void)onLog:(NSString *)logInfo -{ - NSLog(@"RCTDouYinLOG: %@", logInfo); -} - - -@end diff --git a/ios/Douyin.xcodeproj/project.pbxproj b/ios/Douyin.xcodeproj/project.pbxproj deleted file mode 100755 index 1b94d53..0000000 --- a/ios/Douyin.xcodeproj/project.pbxproj +++ /dev/null @@ -1,271 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - B3E7B58A1CC2AC0600A0062D /* Douyin.m in Sources */ = {isa = PBXBuildFile; fileRef = B3E7B5891CC2AC0600A0062D /* Douyin.m */; }; -/* End PBXBuildFile section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 58B511D91A9E6C8500147676 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = "include/$(PRODUCT_NAME)"; - dstSubfolderSpec = 16; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - 134814201AA4EA6300B7C361 /* libDouyin.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libDouyin.a; sourceTree = BUILT_PRODUCTS_DIR; }; - B3E7B5881CC2AC0600A0062D /* Douyin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Douyin.h; sourceTree = ""; }; - B3E7B5891CC2AC0600A0062D /* Douyin.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Douyin.m; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 58B511D81A9E6C8500147676 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 134814211AA4EA7D00B7C361 /* Products */ = { - isa = PBXGroup; - children = ( - 134814201AA4EA6300B7C361 /* libDouyin.a */, - ); - name = Products; - sourceTree = ""; - }; - 58B511D21A9E6C8500147676 = { - isa = PBXGroup; - children = ( - B3E7B5881CC2AC0600A0062D /* Douyin.h */, - B3E7B5891CC2AC0600A0062D /* Douyin.m */, - 134814211AA4EA7D00B7C361 /* Products */, - ); - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 58B511DA1A9E6C8500147676 /* Douyin */ = { - isa = PBXNativeTarget; - buildConfigurationList = 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "Douyin" */; - buildPhases = ( - 58B511D71A9E6C8500147676 /* Sources */, - 58B511D81A9E6C8500147676 /* Frameworks */, - 58B511D91A9E6C8500147676 /* CopyFiles */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = Douyin; - productName = RCTDataManager; - productReference = 134814201AA4EA6300B7C361 /* libDouyin.a */; - productType = "com.apple.product-type.library.static"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 58B511D31A9E6C8500147676 /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0920; - ORGANIZATIONNAME = Facebook; - TargetAttributes = { - 58B511DA1A9E6C8500147676 = { - CreatedOnToolsVersion = 6.1.1; - }; - }; - }; - buildConfigurationList = 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "Douyin" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - ); - mainGroup = 58B511D21A9E6C8500147676; - productRefGroup = 58B511D21A9E6C8500147676; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 58B511DA1A9E6C8500147676 /* Douyin */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXSourcesBuildPhase section */ - 58B511D71A9E6C8500147676 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - B3E7B58A1CC2AC0600A0062D /* Douyin.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin XCBuildConfiguration section */ - 58B511ED1A9E6C8500147676 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - }; - name = Debug; - }; - 58B511EE1A9E6C8500147676 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = YES; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 58B511F01A9E6C8500147676 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - HEADER_SEARCH_PATHS = ( - "$(inherited)", - /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, - "$(SRCROOT)/../../../React/**", - "$(SRCROOT)/../../react-native/React/**", - ); - LIBRARY_SEARCH_PATHS = "$(inherited)"; - OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = Douyin; - SKIP_INSTALL = YES; - }; - name = Debug; - }; - 58B511F11A9E6C8500147676 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - HEADER_SEARCH_PATHS = ( - "$(inherited)", - /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, - "$(SRCROOT)/../../../React/**", - "$(SRCROOT)/../../react-native/React/**", - ); - LIBRARY_SEARCH_PATHS = "$(inherited)"; - OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = Douyin; - SKIP_INSTALL = YES; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "Douyin" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 58B511ED1A9E6C8500147676 /* Debug */, - 58B511EE1A9E6C8500147676 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "Douyin" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 58B511F01A9E6C8500147676 /* Debug */, - 58B511F11A9E6C8500147676 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 58B511D31A9E6C8500147676 /* Project object */; -} diff --git a/ios/Douyin.xcworkspace/contents.xcworkspacedata b/ios/Douyin.xcworkspace/contents.xcworkspacedata deleted file mode 100755 index bc7645d..0000000 --- a/ios/Douyin.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/package.json b/package.json index 5f31882..1be2ec5 100755 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "react-native-douyin-lib", + "name": "@react-native-ohos/react-native-douyin-lib", "title": "React Native Douyin", "version": "1.1.4", "description": "抖音登录、分享", @@ -29,5 +29,14 @@ "devDependencies": { "react": "^16.8.3", "react-native": "^0.59.10" - } + }, + "harmony": { + "alias": "react-native-douyin-lib", + "autolinking": { + "etsPackageClassName":"RNDouYinPackage", + "cppPackageClassName":"DouYinPackage", + "cmakeLibraryTargetName": "rnoh_douyin", + "ohPackageName": "@react-native-ohos/react-native-douyin-lib" + } + } }