React-Native 中的发布调试配置

release-debug configuration in React-Native

目前在 React-Native 中,根据 the documentation,要构建用于生产的 iOS 应用程序,您需要:

这严重违反了 12 factor config recommandation,它会导致在持续集成过程中出错。

RN 没有提供开箱即用的策略来了解 JS 代码中的配置环境,导致存在包 react-native-config, which does a great job already, but is not perfect (Xcode is not fully supported).

为什么会这样?是不是因为今天生产中的 RN 应用程序实际上很少,所以没人关心这个?我们可以做得比 react-native-config 更好,这样就不需要上面列出的步骤了吗?我想要一个命令行,它以我可以 运行 cd android && ./gradlew assembleRelease 相同的方式归档我的应用程序,而无需更改我的配置。

编辑:

Fastlane makes deployment a lot easier through its gym command (thank you Daniel Basedow). Apparently, the philosophy of Xcode is to call environments "schemes", only you cannot store variables in them, or know which scheme you're running in your code... Anyway, David K. Hess found a great way 在你的 Info.plist 中导出你的方案名称,然后在你的 Objective C 代码中,这意味着我现在可以根据当前方案选择我的包, 不要碰我的代码。

这是我的代码: NSString *schemeName = [[[NSBundle mainBundle] infoDictionary] valueForKey:@"SchemeName"]; if ([schemeName isEqualToString:@"scheme1"]) { jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.ios.bundle?platform=ios&dev=true"]; } else if ([schemeName isEqualToString:@"scheme2"]) { jsCodeLocation = [NSURL URLWithString:@"http://<my_local_ip_address>:8081/index.ios.bundle?platform=ios&dev=true"]; } else if ([schemeName isEqualToString:@"scheme3"]) { jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; }

现在我的问题是:我还想知道我在我的 JS 代码中 运行ning 是哪个方案。 react-native-config 的方式自我描述为 hacky,并且考虑到信息已经在我的 Objective C 代码中这一事实过于复杂。有没有办法将这些信息桥接到我的 JS 代码?

只知道我运行宁是哪个方案不如能够设置环境变量,但至少我可以通过改变我的方案来在环境之间切换。

编辑 2:

我设法将我的方案导出到我的 JS 代码中。我使用以下代码创建了一个 cocoa touch class:

//  RNScheme.h

#import <Foundation/Foundation.h>
#import "RCTBridgeModule.h"

@interface RNScheme : NSObject <RCTBridgeModule>

@end




//  RNScheme.m

#import "RNScheme.h"

@interface RNScheme()

@end

@implementation RNScheme
{

}

RCT_EXPORT_MODULE()

- (NSDictionary *)constantsToExport
{
  NSString *schemeName = [[[NSBundle mainBundle] infoDictionary] valueForKey:@"SchemeName"];
  NSLog(@"%@", schemeName);
  return @{
           @"scheme_name": schemeName,
           };
}

@end

然后在我的 JS 代码中:

import {NativeModules} from 'react-native'
let scheme = NativeModules.RNScheme.scheme_name

编辑 3:

实际上除了使用方案还有另一种方法。您可以通过以下步骤创建新的 "configurations"("Release" 和 "Debug" 称为配置)(感谢 CodePush):

  1. 在项目中打开您的 Xcode 项目和 select 您的项目 导航器 window

  2. 确保项目节点是 selected,而不是你的节点之一 目标

  3. Select 信息选项卡

  4. 单击“配置”部分中的 + 按钮,然后 select 您要复制哪个配置

然后您可以根据您的配置定义具有不同值的键。

  1. Select 您的应用目标

  2. 选择构建设置

  3. 转到用户定义的部分(在滚动区域的底部)

  4. 您可以根据您的配置定义不同值的常量(例如API_ENDPOINT

然后您可以在 Info.plist 文件中引用此值:

  1. 打开您的 Info.plist 文件

  2. 创建一个新值并为其命名 (ApiEndpoint)

  3. 给它赋值 $(API_ENDPOINT) 或者你给常量起的任何名字

现在您可以使用我在第二次编辑此问题时提供给您的代码在您的代码中引用此值。

您可以为每个配置创建一个方案以快速从一个切换到另一个,或者每次都更改构建配置(选项单击 运行 按钮)。

在您的 AppDelegate 中,您可以像这样使用正确的包

#ifdef DEBUG
  jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.ios.bundle?platform=ios&dev=true"];
#else
  jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
#endif

当您进行发布构建时,未设置 DEBUG 标志。您还可以根据构建类型使用不同的文件作为 Info.plist。在某些情况下,您可能需要使用生产 JS 包进行 Xcode 调试构建,反之亦然。在这种情况下,您需要触摸代码。

从命令行构建 ios 应用程序可能有点棘手。您描述的问题并非特定于 react-native,而是 Xcode 构建系统。如果您还没有,请查看 fastlane,尤其是 gym 命令。比直接用xcodebuild简单多了。

但是你还是要定义你的方案。