ReactNative: 將自定義的ReactNative組件製做成第三方庫的詳細流程(製做-->發佈)

1、簡介html

在講本篇博文以前,須要你熟知怎麼自定義ReactNative組件,而後纔好學習將自定義的ReactNative組件製做成第三方庫。本文中的自定義的ReactNative組件LoginManager API 源自上篇文章,因此須要先看一下上篇博文。言歸正傳,ReactNative的確提供了一個很是便捷的方式來擴展Native模塊。若是要把模塊作成第三方組件的話,還有一些工做要作:首先以一個靜態庫工程來編譯模塊代碼,提供JavaScript的封裝,最後建立Package.json來支持node的引用。在步驟開始以前,我先把上篇文章中建立Native原生模塊的LoginManager API組件的類貼出來,以下所示:node

LoginManager.hreact

//
//  LoginManager.h
//  RNDemo
//
//  Created by 夏遠全 on 2020/1/16.
//  Copyright © 2020 Facebook. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <React/RCTUtils.h>
#import <React/RCTEventDispatcher.h>
#import <React/RCTBridgeModule.h>

NS_ASSUME_NONNULL_BEGIN

//OC中定義一個枚舉並導出
typedef NS_ENUM(NSInteger, MoveDiretion){
    MoveDiretionNone,
    MoveDiretionLeft,
    MoveDiretionRight,
    MoveDiretionBottom,
    MoveDiretionTop
};

@interface LoginManager : NSObject<RCTBridgeModule>

@end

NS_ASSUME_NONNULL_END
View Code

LoginManager.mios

//
//  LoginManager.m
//  RNDemo
//
//  Created by 夏遠全 on 2020/1/16.
//  Copyright © 2020 Facebook. All rights reserved.
//

#import "LoginManager.h"

#ifdef DEBUG
#define NSLog(format, ...) printf("[%s] %s [第%d行] %s\n", __TIME__, __FUNCTION__, __LINE__, [[NSString stringWithFormat:format, ## __VA_ARGS__] UTF8String]);
#else
#define NSLog(format, ...)
#endif

@implementation LoginManager

//初始化, 添加屏幕旋轉監聽者
-(instancetype)init {
    self = [super init];
    if (self) {
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationDidChange:) name:UIDeviceOrientationDidChangeNotification object:nil];
    }
    return self;
}

//導出模塊類
RCT_EXPORT_MODULE();


//重映射,auth爲code方法的新名稱
RCT_REMAP_METHOD(auth,code:(NSString *)account{
                      NSLog(@"%s---獲取驗證----",__func__);
                      NSLog(@"account----%@",account);
                  });

//login爲方法名
RCT_EXPORT_METHOD(login:(NSString *)account password:(NSString *)password{
                      NSLog(@"%s---登陸帳號----",__func__);
                      NSLog(@"account----%@",account);
                      NSLog(@"password----%@",password);
                  });

//logout爲方法名
RCT_EXPORT_METHOD(logout:(NSString *)account{
                      NSLog(@"%s---退出帳號----",__func__);
                      NSLog(@"account----%@",account);
                  });

//設置普通的回調函數
//fetchUserInfoWithToken爲方法名,successCallback爲成功回調,failureCallback爲失敗回調
RCT_EXPORT_METHOD(fetchUserInfoWithToken:(NSString *)token success:(RCTResponseSenderBlock)successCallback failure:(RCTResponseErrorBlock)failureCallback
    {
            if(token.length>0 && successCallback){
                  successCallback(@[
                                    @"account = xiayuanquan",
                                    @"password = 123456",
                                    [NSString stringWithFormat:@"token = %@",token]
                                  ]);
            }
            else{
                  if(failureCallback){
                        failureCallback(
                                          [[NSError alloc] initWithDomain:NSOSStatusErrorDomain
                                                                     code:404
                                                                 userInfo: @{NSLocalizedDescriptionKey: @"token exception"}]
                                        );
                  }
            }
    });


//設置異步處理的回調函數
//sendMessage爲方法名,successCallback爲成功回調,failureCallback爲失敗回調
RCT_EXPORT_METHOD(sendMessage:(NSString *)message success:(RCTPromiseResolveBlock)successCallback failure:(RCTPromiseRejectBlock)failureCallback
    {
            if(message.length>0 && successCallback){
                  successCallback(@"發送成功!");
            }
            else{
                  if(failureCallback){
                      failureCallback(@"300",@"發送失敗",nil);
                  }
            }
    });


//重寫constantsToExport, 枚舉常量導出
- (NSDictionary<NSString *, id> *)constantsToExport {
   return @{
        @"MoveDiretionNone": @(MoveDiretionNone),
        @"MoveDiretionLeft": @(MoveDiretionLeft),
        @"MoveDiretionRight": @(MoveDiretionRight),
        @"MoveDiretionBottom": @(MoveDiretionBottom),
        @"MoveDiretionTop": @(MoveDiretionTop)
   };
}

//定義一個移動方法,根據傳入的枚舉值移動
//move爲方法名
RCT_EXPORT_METHOD(move:(MoveDiretion)moveDiretion{
                    switch(moveDiretion){
                        case MoveDiretionNone:
                             NSLog(@"仍保持原始位置 --- MoveDiretionNome");
                        break;
                        case MoveDiretionLeft:
                             NSLog(@"向左邊移動位置 --- MoveDiretionLeft");
                        break;
                        case MoveDiretionRight:
                             NSLog(@"向右邊移動位置 --- MoveDiretionRight");
                        break;
                        case MoveDiretionBottom:
                             NSLog(@"向下邊移動位置 --- MoveDiretionBottom");
                        break;
                        case MoveDiretionTop:
                             NSLog(@"向上邊移動位置 --- MoveDiretionTop");
                        break;
                    }
                 });


//能夠重寫隊列,給當前模塊類指定自定義的串行隊列。若不指定,則系統默認會給當前模塊類隨機分配一個串行隊列。
//這個方法一旦重寫。當前模塊的全部方法均會在該自定義的串行隊列中異步執行
-(dispatch_queue_t)methodQueue{
    return dispatch_queue_create("com.facebook.ReactNative.LoginManagerQueue", DISPATCH_QUEUE_SERIAL);
}

//定義一個方法,獲取線程和隊列信息
//thread爲方法名
RCT_EXPORT_METHOD(thread:(BOOL)newQueue{
                  
              const char *queueName = dispatch_queue_get_label([self methodQueue]);
              NSLog(@"當前線程1 ------- %@-----%s", [NSThread currentThread], queueName);
              
              if(newQueue){
                  
                  dispatch_async(dispatch_get_main_queue(), ^{
                      const char *queueName2 = dispatch_queue_get_label(dispatch_get_main_queue());
                      NSLog(@"當前線程2 ------- %@ -------%s", [NSThread currentThread], queueName2);
                  });
          
                  dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
                      const char *queueName3 = dispatch_queue_get_label(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0));
                      NSLog(@"當前線程3 ------- %@-------%s", [NSThread currentThread], queueName3);
                  });
              }
          });


//獲取當前屏幕的尺寸
static NSDictionary *Dimensions(){
    CGFloat width = MIN(RCTScreenSize().width, RCTScreenSize().height);
    CGFloat height = MAX(RCTScreenSize().width, RCTScreenSize().height);
    CGFloat scale = RCTScreenScale();
    if(UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation)){
        width = MAX(RCTScreenSize().width, RCTScreenSize().height);
        height = MIN(RCTScreenSize().width, RCTScreenSize().height);
    }
    return @{
        @"width": @(width),
        @"height": @(height),
        @"scale": @(scale)
    };
}
//定義一個方法,獲取屏幕信息
//getDimensions爲方法名
RCT_EXPORT_METHOD(getDimensions:(RCTResponseSenderBlock)callback{
    if (callback) {
        callback(@[[NSNull null], Dimensions()]);
    }
});

//監聽方法,使用RCTEventDispatcher的eventDispatcher調用sendDeviceEventWithName函數發送事件信息
//能夠將事件名稱做爲常量導出,提供給ReactNative中使用,也即添加到constantsToExport方法中的字典中便可。相似上面的枚舉。
@synthesize bridge = _bridge;
-(void)orientationDidChange:(NSNotification *)notification {
  [_bridge.eventDispatcher sendDeviceEventWithName:@"orientationDidChange" body:@{
      @"orientation": UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation) ? @"Landscape": @"Portrait",
      @"Dimensions": Dimensions()}
   ];
}

//移除監聽者
-(void)dealloc{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

@end
View Code

RCTConvert+MoveDiretion.hgit

//
//  RCTConvert+MoveDiretion.h
//  RNDemo
//
//  Created by 夏遠全 on 2020/1/17.
//  Copyright © 2020 Facebook. All rights reserved.
//

#import <React/RCTConvert.h>

NS_ASSUME_NONNULL_BEGIN

@interface RCTConvert (MoveDiretion)

@end

NS_ASSUME_NONNULL_END
View Code

RCTConvert+MoveDiretion.mgithub

//
//  RCTConvert+MoveDiretion.m
//  RNDemo
//
//  Created by 夏遠全 on 2020/1/17.
//  Copyright © 2020 Facebook. All rights reserved.
//

#import "RCTConvert+MoveDiretion.h"
#import "LoginManager.h"

@implementation RCTConvert (MoveDiretion)

//給RCTConvert類添加擴展,這樣在模塊方法調用中使用常量導出的枚舉值,通訊到Native中時,會從整型自動轉換爲定義的枚舉類型
RCT_ENUM_CONVERTER(MoveDiretion,(@{
   @"MoveDiretionNone": @(MoveDiretionNone),
   @"MoveDiretionLeft": @(MoveDiretionLeft),
   @"MoveDiretionRight": @(MoveDiretionRight),
   @"MoveDiretionBottom": @(MoveDiretionBottom),
   @"MoveDiretionTop": @(MoveDiretionTop),
}), MoveDiretionNone, integerValue)

@end
View Code

 

2、步驟web

一、使用xcode建立一個名爲LoginManager的靜態庫。npm

二、打開靜態庫,將上面貼出來的已經實現好了的Native模塊LoginManager API組件的類所有拷貝進去或進行替換。編程

三、選擇Build Settings,配置Header Search Paths路徑。json

6、打開終端,初始化一個新的RN項目,隨意設置一個名稱爲:LoginManagerTestProject。(本人安裝的ReactNative版本較低)

//初始化
react-native init LoginManagerTestProject --version 0.44.3

七、進入目錄node_modules。

//進入node_modules
cd LoginManagerTestProject/node_modules

八、建立要製做的第三庫文件夾,指定名稱爲:react-native-login-manager。

//建立第三方名稱
mkdir react-native-login-manager

九、進入這個第三方庫文件夾。

//進入庫文件
cd react-native-login-manager

十、建立ios文件夾。

//建立ios文件
mkdir ios

十一、將以前建立的靜態庫中的根目錄下的文件所有copy到這個RN工程LoginManagerTestProject/node_modules/react-native-login-manager/ios目錄下。目錄結構以下:

十二、使用xcode打開這個RN工程LoginManagerTestProject,將靜態庫LoginManager的.xcodeproj文件 拖到 RN工程LoginManagerTestProject的Libraries文件下。

1三、手動添加libLoginManager.a靜態包,而後編譯,若是編譯不出錯,則success。

1四、使用終端或者webStorm等編程工具進入到RN工程LoginManagerTestProject/node_modules/react-native-login-manager目錄下,建立index.js文件,它是整個原生模塊的入口,咱們這裏只是將原生LoginManager模塊類進行導出。此時也就完成了第三方庫製做的第一步了,僅僅能夠本身使用。 (還須要發佈到npm上,分享給你們安裝使用)

 

3、測試 

好了,咱先本身測試一下,看看行不行。結果是行的,😆。

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 * @flow
 */

import React, { Component } from 'react';
import {
    AppRegistry,
    StyleSheet,
    View
} from 'react-native';

//使用自定義的react-native-login-manager第三方庫的模塊方法
import LoginManager from 'react-native-login-manager';
LoginManager.auth("xiayuanquan");

//使用LoginManager模塊類的監聽通知
const RCTDeviceEventEmitter = require('RCTDeviceEventEmitter');
let subscription = RCTDeviceEventEmitter.addListener('orientationDidChange', (dimensions) => {
    Object.keys(dimensions).forEach(key => console.log(key, dimensions[key]));
});
//subscription.remove();

export default class LoginManagerTestProject extends Component {
    render() {
        return (
            <View style={styles.container}>

            </View>
        );
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: '#F5FCFF',
    }
});

AppRegistry.registerComponent('LoginManagerTestProject', () => LoginManagerTestProject); 

運行的結果以下所示:標紅部分確實打印出結果了。

2020-01-18 14:42:21.119 [info][tid:main][RCTBatchedBridge.m:77] Initializing <RCTBatchedBridge: 0x6000023cc1c0> (parent: <RCTBridge: 0x6000031c9490>, executor: RCTJSCExecutor)2020-01-18 14:42:21.173 [warn][tid:com.facebook.react.JavaScript][RCTModuleData.mm:220] RCTBridge required dispatch_sync to load RCTDevSettings. This may lead to deadlocks
2020-01-18 14:42:21.173562+0800 LoginManagerTestProject[89258:2044559] RCTBridge required dispatch_sync to load RCTDevSettings. This may lead to deadlocks

[14:30:32] -[LoginManager code:] [第34行] -[LoginManager code:]---獲取驗證----
[14:30:32] -[LoginManager code:] [第35行] account----xiayuanquan
2020-01-18 14:42:21.391340+0800 LoginManagerTestProject[89258:2044406] Running application LoginManagerTestProject ({
    initialProps =     {
    };
    rootTag = 1;
})
2020-01-18 15:20:51.450 [info][tid:com.facebook.react.JavaScript] 'Dimensions', { width: 375, scale: 2, height: 667 }
2020-01-18 15:20:51.450504+0800 LoginManagerTestProject[89634:2069334] 'Dimensions', { width: 375, scale: 2, height: 667 }
2020-01-18 15:20:51.451 [info][tid:com.facebook.react.JavaScript] 'orientation', 'Portrait'
......
2020-01-18 15:21:08.148 [info][tid:com.facebook.react.JavaScript] 'Dimensions', { width: 667, scale: 2, height: 375 }
2020-01-18 15:21:08.149013+0800 LoginManagerTestProject[89634:2069334] 'Dimensions', { width: 667, scale: 2, height: 375 }
2020-01-18 15:21:08.149 [info][tid:com.facebook.react.JavaScript] 'orientation', 'Landscape'
.....

注意事項,若是在xcode11運行時出現類型沒法轉換。多是因爲RN低版本,Xcode11(iOS13)中對未使用的接口選擇器的參數unused字符串屬性進行了更改爲了__unused__,致使ReactNative動態收集接口時不能把聲明的接口進行導入,運行時沒法查找到該接口致使的錯誤。錯誤以下:

2019-09-25 15:16:47.784 [error][tid:main][RCTModuleMethod.m:376] Unknown argument type '__attribute__' in method -[RCTAppState getCurrentAppState:error:]. Extend RCTConvert to support this type.
2019-09-25 15:16:47.784408+0800 example[68797:2090899] Unknown argument type '__attribute__' in method -[RCTAppState getCurrentAppState:error:]. Extend RCTConvert to support this type.

解決辦法是須要修改RCTModuleMethod類,找到RCTParseUnused靜態函數,使用下面這段代碼進行替換(第2行就是新添加的),以下所示:

static BOOL RCTParseUnused(const char **input)
{
  return RCTReadString(input, "__unused") ||
         RCTReadString(input, "__attribute__((__unused__))") ||
         RCTReadString(input, "__attribute__((unused))");
}

 

4、發佈

只有將第三方庫發佈到了npm上,能夠提供給你們安裝並進行使用,這纔算是真正的第三方庫。可是,在將第三方庫發佈到npm上以前,須要先擁有一個npm帳號。

一、查詢是否擁有npm帳號

//查詢
npm whoami

//本人沒有安裝,因此錯誤以下
npm ERR! code ENEEDAUTH
npm ERR! need auth This command requires you to be logged in.
npm ERR! need auth You need to authorize this machine using `npm adduser`
npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/xiayuanquan/.npm/_logs/2020-01-18T07_37_42_133Z-debug.log

二、若沒有則申請註冊一個

//添加一個npm帳號
npm adduser

//本人添加結果以下。 若是註冊成功,npm官方會發來郵件,用戶須要點擊郵件進行驗證。 "Verify your npm email address"。 必定要進行驗證,不然發佈沒法成功。
Username: xiayuanquan
Password:
Email: (this IS public) 137xxxx7163@163.com
Logged in as xiayuanquan on https://registry.npmjs.org/.

擁有了npm帳號後,咱們如今就能夠來進行發佈的步驟了。

一、進入RN項目,使用git命令在github上建立倉庫react-native-login-manager,和咱們的第三方庫進行關聯。

//進入項目
cd /Users/xiayuanquan/Desktop/LoginManagerTestProject/node_modules/react-native-login-manager 

//git初始化
git init .

//關聯遠程倉庫
git remote add origin https://github.com/xiayuanquan/react-native-login-manager.git

二、仍然在LoginManagerTestProject/node_modules/react-native-login-manager目錄下,建立一個package.json文件。發佈到npm以前,必須有這個文件存在,它和index.js目錄結構是平級的。package.json文件包含了module的全部信息,好比名稱、版本、描述、依賴、做者、license等。 使用npm init -y命令來建立package.json,系統幫助完成各個信息的配置(也可使用npm init命令手動一步步輸入配置信息)。

//建立pack.json配置文件
npm init -y

//本人的配置結果以下
Wrote to /Users/xiayuanquan/Desktop/LoginManagerTestProject/node_modules/react-native-login-manager/package.json:
{
  "name": "react-native-login-manager",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "repository": {
    "type": "git",
    "url": "https://gituhb.com/xiayuanquan/react-native-login-manager.git"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

三、若是採用系統幫助建立的pack.json不夠完善,能夠本身打開這個文件進行編輯。例如,若是咱們的第三方庫須要依賴,能夠手動添加一個dependencies屬性。以下所示:pack.json

{
  "name": "react-native-login-manager",
  "version": "1.0.0",
  "description": "this is a third part login library",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "repository": {
    "type": "git",
    "url": "https://gituhb.com/xiayuanquan/react-native-login-manager.git"
  },
  "keywords": [],
  "author": "xiayuanquan",
  "license": "ISC",

  "dependencies": { },
} 

四、好了,pack.json配置完畢後。就能夠將咱們的第三方庫react-native-login-manager發佈到npm上了。

//發佈第三方庫
npm publish

若是發佈失敗,出現以下錯誤,說明發布採用的鏡像源不匹配 (有可能中途不當心切換過)。錯誤以下:

//錯誤日誌以下
........
npm notice === Tarball Details ===
npm notice name:          react-native-login-manager
npm notice version:       1.0.0
npm notice package size:  18.8 kB
npm notice unpacked size: 41.6 kB
npm notice shasum:        3e576dbb0d45bcc5dd5796928abba724552ab724
npm notice integrity:     sha512-NNKLeNL5XJk1l[...]RR+oP0IKtgYBw==
npm notice total files:   11
npm notice
npm ERR! code E403
npm ERR! 403 403 Forbidden - PUT https://registry.npm.taobao.org/react-native-login-manager - [no_perms] Private mode enable, only admin can publish this module
npm ERR! 403 In most cases, you or one of your dependencies are requesting
npm ERR! 403 a package version that is forbidden by your security policy.

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/xiayuanquan/.npm/_logs/2020-01-18T08_08_46_345Z-debug.log

解決辦法就是先切換源,而後登陸npm,再發布。本人採用nrm管理的源,因此使用nrm切換。nrm管理npm源請參看個人這篇文章,nrm管理npm源。方法以下:

//查看當前源
nrm current       //顯示結果:taobao

//切換源
nrm use npm       //顯示結果:Registry has been set to: https://registry.npmjs.org/

//再查看
nrm current       //顯示結果:npm

//登陸npm
npm login        //顯示結果: Username: xiayuanquan
                            Password:
                               Email: (this IS public) 137xxxx7163@163.com
                            Logged in as xiayuanquan on https://registry.npmjs.org/.

//從新發布
npm publish

//此時,發佈成功,結果以下
npm notice
npm notice 📦  react-native-login-manager@1.0.0
npm notice === Tarball Contents ===
npm notice 587B   ios/LoginManager/LoginManager.h
npm notice 264B   ios/LoginManager/RCTConvert+MoveDiretion.h
npm notice 129B   index.js
npm notice 428B   package.json
npm notice 7.6kB  ios/LoginManager/LoginManager.m
npm notice 725B   ios/LoginManager/RCTConvert+MoveDiretion.m
npm notice 10.8kB ios/LoginManager.xcodeproj/project.pbxproj
npm notice 238B   ios/LoginManager.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
npm notice 347B   ios/LoginManager.xcodeproj/xcuserdata/xiayuanquan.xcuserdatad/xcschemes/xcschememanagement.plist
npm notice 20.4kB ios/LoginManager.xcodeproj/project.xcworkspace/xcuserdata/xiayuanquan.xcuserdatad/UserInterfaceState.xcuserstate
npm notice 157B   ios/LoginManager.xcodeproj/project.xcworkspace/contents.xcworkspacedata
npm notice === Tarball Details ===
npm notice name:          react-native-login-manager
npm notice version:       1.0.0
npm notice package size:  18.8 kB
npm notice unpacked size: 41.7 kB
npm notice shasum:        74fbf2900e983bc15ad78ef7c62f56c46b331fb3
npm notice integrity:     sha512-gmkR+gIETJabT[...]nG2SwO1ly+Pvg==
npm notice total files:   11
npm notice
+ react-native-login-manager@1.0.0                

發佈成功後,郵箱會收到通知,如「 Successfully published react-native-login-manager@1.0.0」。也能夠登陸npm網站進行查看:https://www.npmjs.com。以下所示:

五、至此,咱們已經成功把module發佈到了npmjs.org。固然,咱們也須要將咱們的代碼發佈到github。

//來取分支
git pull origin master

//添加文件
git add .

//提交日誌
git commit -m 'add all files of project'

//提交分支
git push origin master

 

5、驗證

一、建立一個新的RN項目進行測試。以下所示:

//建立RN項目
react-native init TestThirdPart --version 0.44.3

二、安裝react-native-login-manager第三方庫。以下所示:

//安裝庫
npm install react-native-login-manager --save

三、將第三方庫連接到RN項目中。以下所示:

//連接第三方庫
react-native link react-native-login-manager

四、使用xcode打開項目。以下所示:

五、測試結果。以下所示:

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 * @flow
 */

import React, { Component } from 'react';
import {
    AppRegistry,
    StyleSheet,
    View
} from 'react-native';

import LoginManager from 'react-native-login-manager';

//使用自定義的react-native-login-manager第三方庫的模塊方法
LoginManager.auth("13710371234");

//使用LoginManager模塊類的監聽通知
const RCTDeviceEventEmitter = require('RCTDeviceEventEmitter');
let subscription = RCTDeviceEventEmitter.addListener('orientationDidChange', (dimensions) => {
    Object.keys(dimensions).forEach(key => console.log(key, dimensions[key]));
});
//subscription.remove();

export default class TestThirdPart extends Component {
    render() {
        return (
            <View style={styles.container}>

            </View>
        );
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: '#F5FCFF',
    }
});

AppRegistry.registerComponent('TestThirdPart', () => TestThirdPart);
//日誌以下
.......

2020-01-18 17:35:58.759817+0800 TestThirdPart[96482:2177939] RCTBridge required dispatch_sync to load RCTDevSettings. This may lead to deadlocks

[17:35:41] -[LoginManager code:] [第34行] -[LoginManager code:]---獲取驗證----
[17:35:41] -[LoginManager code:] [第35行] account----13710371234

2020-01-18 17:36:15.866355+0800 TestThirdPart[96482:2177905] [] nw_socket_handle_socket_event [C3.1:1] Socket SO_ERROR [61: Connection refused]
2020-01-18 17:36:15.868757+0800 TestThirdPart[96482:2177905] [] nw_socket_handle_socket_event [C3.2:1] Socket SO_ERROR [61: Connection refused]
2020-01-18 17:36:15.870211+0800 TestThirdPart[96482:2177912] [] nw_connection_get_connected_socket [C3] Client called nw_connection_get_connected_socket on unconnected nw_connection
2020-01-18 17:36:15.870855+0800 TestThirdPart[96482:2177912] TCP Conn 0x600000cd8cc0 Failed : error 0:61 [61]
2020-01-18 17:36:15.888 [info][tid:main][RCTRootView.m:295] Running application TestThirdPart ({
    initialProps =     {
    };
    rootTag = 1;
})
2020-01-18 17:36:15.888347+0800 TestThirdPart[96482:2177597] Running application TestThirdPart ({
    initialProps =     {
    };
    rootTag = 1;
})
2020-01-18 17:36:15.891 [info][tid:com.facebook.react.JavaScript] 'Dimensions', { width: 375, scale: 2, height: 667 }
2020-01-18 17:36:15.891136+0800 TestThirdPart[96482:2177939] 'Dimensions', { width: 375, scale: 2, height: 667 }
2020-01-18 17:36:15.891 [info][tid:com.facebook.react.JavaScript] 'orientation', 'Portrait'
2020-01-18 17:36:15.891625+0800 TestThirdPart[96482:2177939] 'orientation', 'Portrait'
2020-01-18 17:36:15.892 [info][tid:com.facebook.react.JavaScript] 'Dimensions', { width: 375, scale: 2, height: 667 }
2020-01-18 17:36:15.892121+0800 TestThirdPart[96482:2177939] 'Dimensions', { width: 375, scale: 2, height: 667 }
2020-01-18 17:36:15.892 [info][tid:com.facebook.react.JavaScript] 'orientation', 'Portrait'
2020-01-18 17:36:15.892490+0800 TestThirdPart[96482:2177939] 'orientation', 'Portrait'
........

 

6、完結

至此,一個真正的ReactNative第三方庫開發完成。累死我了。。。。

相關文章
相關標籤/搜索