【发布时间】:2016-11-16 05:44:41
【问题描述】:
目前在 React-Native 中,根据the documentation,要构建您的 iOS 应用程序以进行生产,您需要:
- 将您的方案更改为
Release - 更改您的
AppDelegate.m以加载正确的包 - 将您的
Info.pList更改为 ATS
这是对12 factor config recommandation 的严重违反,它会导致在持续集成过程中出现错误。
RN 没有提供开箱即用的策略来了解 JS 代码中的配置环境,导致存在包react-native-config,它已经做得很好,但并不完美(Xcode is not fully supported) .
为什么会这样?是不是因为现在生产中的 RN 应用程序实际上很少,所以没人关心这个?我们能比react-native-config 做得更好,这样就不需要上面列出的步骤了吗?我想要一个命令行来归档我的应用程序,就像我可以运行 cd android && ./gradlew assembleRelease 一样,而不需要对我的配置进行任何更改。
编辑:
Fastlane 通过其gym 命令使部署变得更加容易(感谢 Daniel Basedow)。显然,Xcode 的理念是将环境称为“方案”,只有你不能在其中存储变量,或者知道你在代码中运行的是哪个方案……无论如何,David K. Hess 找到了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 代码中运行的方案。 react-native-config 的方式自称为 hacky,而且考虑到信息已经在我的 Objective C 代码中这一事实过于复杂。有没有办法将此信息桥接到我的 JS 代码?
只知道自己运行的是哪个scheme还不如能设置环境变量,但至少我只能通过改变scheme来切换环境。
编辑 2:
我设法将我的方案导出到我的 JS 代码中。我使用以下代码创建了一个可可触摸类:
// 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:
除了使用方案之外,实际上还有另一种方法。您可以通过以下步骤创建新的“配置”(“发布”和“调试”称为配置)(感谢CodePush):
打开您的 Xcode 项目并在 Project 中选择您的项目 导航窗口
确保选择项目节点,而不是您的一个 目标
选择信息标签
单击“配置”部分中的 + 按钮并选择 您要复制哪个配置
然后你可以根据你的配置定义不同值的键。
选择您的应用目标
选择构建设置
转到用户定义部分(在滚动区域的底部)
您可以根据您的配置定义具有不同值的常量(例如
API_ENDPOINT)
然后您可以在 Info.plist 文件中引用此值:
打开您的
Info.plist文件创建一个新值并为其命名 (
ApiEndpoint)给它值
$(API_ENDPOINT)或者你给常量取的任何名字
现在您可以使用我在第二次编辑此问题时提供的代码在您的代码中引用此值。
您可以为每个配置创建一个方案以快速从一种切换到另一种,或每次更改构建配置(选项单击运行按钮)。
【问题讨论】:
-
你碰巧也有安卓的例子吗:)
-
fastlane deploy适用于安卓系统。您可以使用 react-native-config 添加配置文件。一个不错的替代方案是 expo.io:所有本地代码都为您抽象,所有配置都是集中式的,并且可以使用 Android 和 iOS 的单个文件。
标签: ios configuration react-native release