Closed sunny635533 closed 1 year ago
After installing the SDK using Cocoapods, you can import the SDK into your Objective-C files using the following imports:
#import <TikTokOpenSDKCore/TikTokOpenSDKCore-Swift.h>
#import <TikTokOpenAuthSDK/TikTokOpenAuthSDK-Swift.h>
#import <TikTokOpenShareSDK/TikTokOpenShareSDK-Swift.h>
@stephen-boyle i follow you to import these,but still has error.
my pod file codes is:
#source 'https://github.com/CocoaPods/Specs.git'
require_relative '../node_modules/react-native/scripts/react_native_pods'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
platform :ios, '12.4'
install! 'cocoapods', :deterministic_uuids => false
production = ENV["PRODUCTION"] == "1"
target 'iBooming' do
project 'iBooming'
config = use_native_modules!
flags = get_default_flags()
#tiktok SDK
# pod 'TikTokOpenSDK', '~> 5.0.14'
pod 'TikTokOpenSDKCore', '~> 2.0.0'
pod 'TikTokOpenAuthSDK', '~> 2.0.0'
pod 'SVProgressHUD', '~> 2.2.5'
use_react_native!(
:path => config[:reactNativePath],
# to enable hermes on iOS, change `false` to `true` and then install pods
:production => production,
:hermes_enabled => flags[:hermes_enabled],
:fabric_enabled => flags[:fabric_enabled],
:flipper_configuration => FlipperConfiguration.enabled,
# An absolute path to your application root.
:app_path => "#{Pod::Config.instance.installation_root}/.."
)
target 'iBoomingTests' do
inherit! :complete
# Pods for testing
end
# Enables Flipper.
#
# Note that if you have use_frameworks! enabled, Flipper will not work and
# you should disable the next line.
use_flipper!()
post_install do |installer|
react_native_post_install(installer)
__apply_Xcode_12_5_M1_post_install_workaround(installer)
end
end
What else do I need to configure? Maybe it's convenient for you to provide me with a project example.Thanks.
@sunny635533 You have commented out TikTokOpenSDK
:
# pod 'TikTokOpenSDK', '~> 5.0.14'
pod 'TikTokOpenSDKCore', '~> 2.0.0'
pod 'TikTokOpenAuthSDK', '~> 2.0.0'
Should be:
pod 'TikTokOpenSDKCore'
pod 'TikTokOpenAuthSDK'
pod 'TikTokOpenShareSDK'
If you want to include the project with SPM instead of CocoaPods, you can do that with my fork here: https://github.com/nickdnk/tiktok-opensdk-ios - this would also confirm that the SPM version works with Objective C projects.
@nickdnk i dont want to include with SPM, because my project is Objective-C's project. TikTokOpenSDK is the sdk of Tiktok api V1,but now i want to upgrade to Tiktok api V2 version. So i have commented out TikTokOpenSDK. I found a way to use swift's sdk's method directly with objective-c, First step=> i created "projectName-Bridging-Header.h" file and add these in it,
@import TikTokOpenSDKCore;
@import TikTokOpenAuthSDK;
Second step=> import these class in OC files,
#import "projectName-Bridging-Header.h"
RCT_EXPORT_METHOD(getAuthCode:(NSString *)state scopes:(NSString *)scope resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
NSLog(@"-----------state=%@,scope=%@",state,scope);
dispatch_async(dispatch_get_main_queue(), ^{
NSArray *scopesArray = [scope componentsSeparatedByString:@","];
NSSet<NSString *> *scopeSet = [NSSet setWithArray:scopesArray];
NSString *redirectUri = @"https://kkk.test.com/app/";
TTKSDKAuthRequest *authRequest=[[TTKSDKAuthRequest alloc] initWithScopes:scopeSet redirectURI:redirectUri];
authRequest.isWebAuth = false;
[authRequest send:^(id<TTKSDKBaseResponse> response) {
NSLog(@"========== TTKSDKBaseResponse ====%@",response);
if(response == nil){
NSError *error=[NSError errorWithDomain:@"error domain" code:-100 userInfo:nil];
reject(@"getAuthCode fail",@"error",error);
}else{
TTKSDKAuthResponse *myresponse = (TTKSDKAuthResponse *)response;
if(myresponse.errorCode == 0){
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
[dict setValue:0 forKey:@"errorCode"];
[dict setValue:myresponse.errorDescription forKey:@"errorMsg"];
[dict setValue:myresponse.authCode forKey:@"authCode"];
[dict setValue:scope forKey:@"grantedPermissions"];
//how to get codeVerifier???
// TTKSDKCodeVerifier *verifier = authRequest.pkce;
// [dict setValue:authRequest.pkce.codeVerifier forKey:@"codeVerifier"];
[dict setValue:redirectUri forKey:@"redirectUri"];
}else{
NSError *error=[NSError errorWithDomain:@"error domain" code:-100 userInfo:nil];
reject(@"getAuthCode fail",@"error",error);
}
}
}];
});
}
Third step => add these in AppDelege.m,
#import "projectName-Bridging-Header.h"
- (BOOL)application:(UIApplication *)application openURL:(nonnull NSURL *)url options:(nonnull NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
if([TTKSDKURLHandler handleOpenURL:url]){
return true;
}
return [RCTLinkingManager application:application openURL:url options:options];
}
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
if([TTKSDKURLHandler handleOpenURL:url]){
return true;
}
return [RCTLinkingManager application:application openURL:url
sourceApplication:sourceApplication annotation:annotation];
}
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
{
if([TTKSDKURLHandler handleOpenURL:url]){
return true;
}
return NO;
}
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void(^)(NSArray * __nullable restorableObjects))restorationHandler{
NSLog(@"=========== restorationHandler ========%@",userActivity.webpageURL);
if([TTKSDKURLHandler handleOpenURL:userActivity.webpageURL]){
return true;
}
return false;
}
At last i get an error,
[TTKSDKURLHandler handleOpenURL:userActivity.webpageURL] alaway return "null", i hope it can return true. And never come in here,
[authRequest send:^(id
SPM works with Objective-C. That's what I just wrote. You just need to add all 3 packages and import them in your bridging header file.
While you don't need CocoaPods at all, the pods I listed are the ones you need to include. They are all version 2.0. Note that what I wrote was TikTokOpenSDKCore
while you wrote TikTokOpenSDK
. The latter is version 1.
I just tested with an Objective-C project, and all you need to do if using SPM is:
@import TikTokOpenAuthSDK; // (or Core/Share; the library you need)
In your header files where you want to use the library, i.e. AppDelegate.h
;
@nickdnk I tried add it with SPM, but encountered some problems, can not go to the next step.
Tried several times today, still can't download.
You added this repo which does not support SPM yet. The link I posted was this: https://github.com/nickdnk/tiktok-opensdk-ios - it is my fork of this repo which supports SPM.
Still has same problem,
It's not the same problem. I can't read the error message. You'll have to post the full error.
Try using Branch: main
instead of "up to next major".
And also remember to check all 3 packages when it asks you which you want to add to your project.
First step,choose=>Branch: main,
Sceond Step:
Still has error. But thank you for your reply.
You are not posting the full error, so I cannot help you debug it. It works in my Objective C project.
After adding the package, you can change its parameters here:
And it should be linked as a framework in your app's target as well here:
@sunny635533 我也遇到这个问题, handleOpenURL
一直返回false, 查不出原因. 然后我自己解析url, 把结果返回给RN了, 代码给你参考下
@objc
public static func handleOpenURL(_ url: URL) -> Bool {
// TIkTok 官方代码
// return TikTokURLHandler.handleOpenURL(url);
// 由于TikTok SDK一直返回false, 查不出原因, 所以自己解析url返回结果
do {
guard let comps = URLComponents(url: url, resolvingAgainstBaseURL: false) else {
throw TikTokResponseError.failToParseURL
}
guard let comps = URLComponents(url: url, resolvingAgainstBaseURL: false) else {
throw TikTokResponseError.failToParseURL
}
guard let dict = comps.queryItems?.reduce(into: [String: String](), {
$0[$1.name] = $1.value
}) else {
throw TikTokResponseError.failToParseURL
}
if (dict["from_platform"] == "tiktokopensdk") {
let errorDescription = dict["error_description"]
let errorCode = dict["error_code"]
let authCode = dict["code"]
if (errorCode == "0") {
resolve?([
"code": authCode,
"codeVerifier": codeVerifier,
"redirectUri": redirectUri
]);
} else {
reject?(errorCode, errorDescription, nil);
}
return true
}
} catch {
}
return false;
}
@chenqi777 你好,resolve 和 reject 怎么弄成全局静态调用?android集成使用没问题,但ios我不是很熟悉怎么写,你方便把代码贴完整出来给我参考下么?谢谢!
@sunny635533 iOS我也不熟, 我是写了个Swift桥接代码, 然后用OC来掉Swift
import Foundation
import TikTokOpenSDKCore
import TikTokOpenAuthSDK
@objc
final public class TikTokBridge: NSObject {
static var resolve : RCTPromiseResolveBlock? = nil;
static var reject : RCTPromiseRejectBlock? = nil;
static var codeVerifier : String = "";
static var redirectUri : String = RNCConfig.env(for: "TIKTOK_IOS_REDIRECT_URI");
@objc
public static func handleOpenURL(_ url: URL) -> Bool {
// TIkTok 官方代码
// return TikTokURLHandler.handleOpenURL(url);
// 由于TikTok SDK一直返回false, 查不出原因, 所以自己解析url返回结果
do {
guard let comps = URLComponents(url: url, resolvingAgainstBaseURL: false) else {
throw TikTokResponseError.failToParseURL
}
guard let comps = URLComponents(url: url, resolvingAgainstBaseURL: false) else {
throw TikTokResponseError.failToParseURL
}
guard let dict = comps.queryItems?.reduce(into: [String: String](), {
$0[$1.name] = $1.value
}) else {
throw TikTokResponseError.failToParseURL
}
if (dict["from_platform"] == "tiktokopensdk") {
let errorDescription = dict["error_description"]
let errorCode = dict["error_code"]
let authCode = dict["code"]
if (errorCode == "0") {
resolve?([
"code": authCode,
"codeVerifier": codeVerifier,
"redirectUri": redirectUri
]);
} else {
reject?(errorCode, errorDescription, nil);
}
return true
}
} catch {
}
return false;
}
@objc
public static func login(_ resolve1: @escaping RCTPromiseResolveBlock, reject1: @escaping RCTPromiseRejectBlock) {
let authRequest = TikTokAuthRequest(scopes: ["user.info.basic", "user.info.profile", "user.info.stats", "video.list", "video.publish", "video.upload"],
redirectURI: redirectUri);
/**
TIkTok 官方代码
由于TikTok SDK一直返回false, 查不出原因, 所以自己解析url返回结果
authRequest.send { response in
/* Step 3 */
guard let authResponse = response as? TikTokAuthResponse else { return }
if authResponse.errorCode == .noError {
print("Auth code: \(authResponse.authCode)")
} else {
print("Authorization Failed!")
}
}
*/
codeVerifier = authRequest.pkce.codeVerifier;
resolve = resolve1;
reject = reject1;
authRequest.send();
}
}
可以在RN的module把resolve 和 reject传过去
RCT_REMAP_METHOD(login, findEventsWithResolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
[TikTokBridge login:resolve reject1:reject];
}
@chenqi777 通过你的代码,我之前遇到的问题找到解决方法了,[TTKURLHandler handleOpenURL:url] 是返回true,完整代码: TikokUtils 类(swift)=>
//
// TikTokUtils.swift
// iBooming
//
// Created by sunny on 2023/6/29.
//
import Foundation
import TikTokOpenSDKCore
import TikTokOpenAuthSDK
//@objcMembers public class TikokUtils : NSObject{
@objc
final public class TikokUtils: NSObject {
static var resolve : RCTPromiseResolveBlock? = nil;
static var reject : RCTPromiseRejectBlock? = nil;
// public static var instance = TikokUtils()
public func handleOpenURL(url: URL)-> Bool{
if TikTokURLHandler.handleOpenURL(url) {
print("======= handleOpenURL true =====",url);
return true
}
print("======= handleOpenURL false =====")
return false;
}
// //获取code
@objc
public static func getAuthCode(scopes: NSString,resolver:@escaping RCTPromiseResolveBlock,rejecter:@escaping RCTPromiseRejectBlock)->Void{
resolve = resolver;
reject = rejecter;
let scopesArray:Array = scopes.components(separatedBy: ",");
var setScopes: Set<String> = [];
let redirectUri = "https://m.iboomingglobal.com/app/"
let dict = NSMutableDictionary();
for index in 0 ..< scopesArray.count {
setScopes.insert(scopesArray[index])
}
print("===getAuthCode 1111111==== ",setScopes);
let authRequest = TikTokAuthRequest(scopes: setScopes, redirectURI:redirectUri)
authRequest.isWebAuth = false
DispatchQueue.main.sync {
authRequest.send { response in
guard let myresponse = response as? TikTokAuthResponse else {
let errorObj = NSError();
reject?("getAuthCode fail","error",errorObj);
return }
if myresponse.errorCode != .noError {
let message = "Error: \(myresponse.error ?? "") \n Error Description: \(myresponse.errorDescription ?? "")"
let errorObj = NSError();
reject?("getAuthCode fail","error",errorObj);
}else{
dict.setValue(myresponse.errorCode.rawValue, forKey:"errorCode")
dict.setValue(myresponse.errorDescription, forKey:"errorMsg")
dict.setValue(myresponse.authCode, forKey:"authCode")
dict.setValue(scopes, forKey:"grantedPermissions")
dict.setValue(authRequest.pkce.codeVerifier, forKey:"codeVerifier")
dict.setValue(redirectUri, forKey:"redirectUri")
resolve?(dict)
}
print("===getAuthCode 33333==== ", dict);
}
}
}
}
OC和swift的桥接文件: 项目名称-Bridging-Header.h
@import TikTokOpenSDKCore;
@import TikTokOpenAuthSDK;
#import <React/RCTBridgeModule.h>
AppDelegate.m 类
#import "项目名称-Bridging-Header.h"
- (BOOL)application:(UIApplication *)application openURL:(nonnull NSURL *)url options:(nonnull NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
if([TTKSDKURLHandler handleOpenURL:url]){
return true;
}
return [RCTLinkingManager application:application openURL:url options:options];
}
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
if([TTKSDKURLHandler handleOpenURL:url]){
return true;
}
return [RCTLinkingManager application:application openURL:url
sourceApplication:sourceApplication annotation:annotation];
}
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
{
if([TTKSDKURLHandler handleOpenURL:url]){
return true;
}
return NO;
}
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void(^)(NSArray * __nullable restorableObjects))restorationHandler{
BOOL result = [TTKSDKURLHandler handleOpenURL:userActivity.webpageURL];
NSLog(@"=========== restorationHandler ========%@ result=%d",userActivity.webpageURL,result);
if(result){
return true;
}
return false;
}
最后OC桥接给JS调用的方法:
#import "项目名称-Bridging-Header.h"
#import "项目名称-Swift.h"
RCT_EXPORT_METHOD(getNewAuthCode:(NSString *)state scopes:(NSString *)scope resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
NSLog(@"----getNewAuthCode-------state=%@,scope=%@",state,scope);
[TikokUtils getAuthCodeWithScopes:scope resolver:resolve rejecter:reject];
}
js 代码:
NativeModules.TikTokHelper.getNewAuthCode("1687919509192","user.info.basic,video.list").then(async result => {})
@sunny635533 所以问题是出在哪? 是有些参数没传对吗?
@chenqi777 AppDelegate类的这个方法你有重写么? (BOOL)application:(UIApplication )application continueUserActivity:(NSUserActivity )userActivity restorationHandler:(void(^)(NSArray * __nullable restorableObjects))restorationHandler{
@sunny635533 有重写的
@sunny635533 iOS配置Universal Links,这个配置测试成功了?如果成功的话,tiktok开发平台ios配置检查下:
@sunny635533 算了不纠结了, 现在不影响使用, 将就着用了, 有空再看看
在oc代码中 调用authRequest.pkce.codeVerifier 报错Property 'codeVerifier' not found on object of type 'TTKSDKCodeVerifier *',看起来是因为swift代码中的pkce 没有讲codeVerifier 开发给oc代码 应该如何解决啊
@ZhangChao0613 We recently made a fix for this for, please upgrade your SDK version to v2.2.0
my project is objective-C project,but sample codes is use swift. So i dont know how integerate it with objective-c. Please provide sample code with objective-c.Thanks