无法检索.net 编译设置_在编译时检索默认的远程配置值

无法检索.net 编译设置

We have been using Firebase Remote Config at WELT for a while now. As it is written in their documentation,

我们已经在WELT使用Firebase Remote Config已有一段时间了。 正如他们的文档中所写,

You can use Firebase Remote Config to define parameters in your app and update their values in the cloud, allowing you to modify the appearance and behaviour of your app without distributing an app update.

您可以使用Firebase Remote Config在您的应用程序中定义参数并在云中更新它们的值,从而允许您在不分发应用程序更新的情况下修改应用程序的外观和行为。

Especially the last phrase is relevant to us, we do not want to release a new version to the App Store or Google Play every time we want to change a value in our configuration. We use Remote Config manyfold in our News app, e.g. specifying our backend endpoints or dynamically displaying different sections. On top of that, we can run our A/B test experiments through it, having two different variants of a value and determining which one is more effective according to a subject’s response.

特别是最后一句话与我们相关,我们不想每次想要更改配置值时向App Store或Google Play发布新版本。 我们在新闻应用程序中大量使用了远程配置,例如,指定后端端点或动态显示不同的部分。 最重要的是,我们可以通过它进行A / B测试实验,具有两个不同的值变体,并根据受试者的React确定哪个更有效。

It is because of that that we need it to be fast and promptly available, right from the user first app start up. Since we use it for critical features, it is also an essential requirement that the process is robust; if for some reason the fetching of a value fails, we should have default values as fallbacks. That avoids any critical state in the app for lack of a necessary value.

因此,我们需要从用户第一个应用程序启动起就快速,及时地使用它。 由于我们将其用于关键功能,因此流程的稳健性也是必不可少的要求; 如果由于某种原因无法获取值,则应使用默认值作为后备。 这样可以避免由于缺少必要的值而导致应用中的任何关键状态。

As I mentioned before, we face an instance of this problem right at the first start. At this point, Remote Config values are not fetched yet, therefore having the cache totally empty. Since we need values before even the fetch happens, we will have to consume the statically defined default values.

如前所述,我们从一开始就面临着这个问题的实例。 此时,尚未获取远程配置值,因此使缓存完全为空。 由于即使在提取之前我们都需要值,所以我们将必须使用静态定义的默认值。

Once acknowledged the need of defining some default values, we had to find the proper way to implement it. We firstly resorted to the simplest way, to make use of the API method to define in our code these default values, and pass them through an NSDictionary. On Android meanwhile they have to do the same in their code.

一旦认识到需要定义一些默认值,我们就必须找到实现它的正确方法。 我们首先采用最简单的方法,即利用API方法在代码中定义这些默认值,并将它们传递给NSDictionary。 同时,在Android上,他们必须在代码中执行相同的操作。

改善 (The improvement)

That solution worked fine, but soon we found out that there was room for optimisation given some evident caveats. Namely:

该解决方案效果很好,但是很快我们发现,由于一些明显的警告,还有优化的空间。 即:

  • We have duplicated code in both iOS and Android

    我们在iOS和Android中都有重复的代码
  • We have two sources of truth, the Remote Config dashboard and our code.

    我们有两个事实来源,即“远程配置”仪表板和我们的代码。
  • This means that we have an extra layer to maintain.

    这意味着我们还有一个额外的层要维护。

Somehow this is precisely what we were trying to avoid with Firebase Remote Config. What if we could even make that dynamic?

某种程度上,这正是我们试图通过Firebase Remote Config避免的。 如果我们什至可以使它动态化怎么办?

At this moment we thought of Xcode Build Phases, and the Remote Config API. What if we could download the current values of our Remote Config Dashboard as a Build Phase before compiling, and use these values synchronously first thing when we start the app? That way we would forget about the need of maintaining the code in both platforms, and the values will be updated with the latest version at compile time. With that on mind, we started to work.

此刻,我们想到了Xcode的构建阶段和Remote Config API。 如果我们可以在编译之前下载远程配置仪表板的当前值作为构建阶段,并在启动应用程序时首先同步使用这些值怎么办? 这样,我们将无需在两个平台上都维护代码,并且在编译时将使用最新版本来更新值。 考虑到这一点,我们开始工作。

剧本 (The Script)

The first step is then to create a script to be called at Build time, generating a file to be copied to the project also at Build time. We chose Python given its learning ease, readability and Google support in Firebase Remote Config. And why not say it, it is a cool language!

然后,第一步是创建一个在Build时调用的脚本,生成一个文件,该文件也在Build时复制到项目中。 我们选择Python是因为它的易学性,可读性和Firebase Remote Config中的Google支持。 为什么不说呢,这是一种很酷的语言!

As specified in the docs, we need an access token to authenticate and authorize API requests:

docs中所指定,我们需要一个访问令牌来认证和授权API请求:

In the Firebase console, open Settings > Service Accounts.

在Firebase控制台中,打开“设置”>“ 服务帐户”

Click Generate New Private Key, then confirm by clicking Generate Key.

单击生成新私钥 ,然后单击生成密钥进行确认。

Securely store the JSON file containing the key.

安全地存储包含密钥的JSON文件。

Ideally you add that file to the ignore repo file, but if you still need it to run in your CI you can encrypt it as we will detail later.

理想情况下,您可以将该文件添加到ignore repo文件中,但是如果仍然需要在CI中运行该文件,则可以对其进行加密,我们将在后面详细介绍。

Apart from it, we obviously need the calling URL that provides us with our configuration values. It has this format:

除此之外,我们显然需要调用URL为我们提供配置值。 它具有以下格式:

https://firebaseremoteconfig.googleapis.com/v1/projects/my-project-id/remoteConfig

Once we have these requirements, we are ready to start writing legit Python code. We want to:

满足这些要求后,我们就可以开始编写合法的Python代码了。 我们想:

  • Make the script accept two parameters, the path for the private key JSON and the output path.

    使脚本接受两个参数,即私钥JSON的路径和输出路径。
  • Create credentials with the JSON file containing the key:

    使用包含密钥的JSON文件创建凭证:
  • Create an Authorized session with the credentials, and use it to call the previously determined URL

    使用凭据创建一个授权会话,并使用它来调用先前确定的URL
  • Parse this values extracting the default values and save it into a JSON file, with the path specified as an argument. Please note that we are getting the default values, so if we are performing an A/B testing case it will not gather that data:

    解析此值以提取默认值,并将其保存到JSON文件中,并将路径指定为参数。 请注意,我们正在获取默认值,因此,如果我们正在执行A / B测试用例,它将不会收集该数据:

Since the Remote Config iOS SDK accepts a PLIST file for defaults values as well, we could at this moment parse and generate that format. However, as this would be used as well on Android, we decided to go for the JSON standard.

由于Remote Config iOS SDK也接受PLIST文件作为默认值,因此我们现在可以解析并生成该格式。 但是,由于这也会在Android上使用,因此我们决定采用JSON标准。

建造阶段 (The Build Phases)

Once we have the script that retrieves the defaults, it is time for the Xcode project to make them available to our code. For that, as we mentioned earlier, we create two build phases. The first one calls the script with the specified parameters:

一旦有了用于检索默认值的脚本,Xcode项目就可以将其提供给我们的代码了。 为此,正如我们前面提到的,我们创建了两个构建阶段。 第一个调用具有指定参数的脚本:

Image for post

The sh code is as follows:

sh代码如下:

Secondly, we need to copy that file into our project. We could have used the already present Copy Bundle Resources phase, but we wanted to make it more explicit and visible:

其次,我们需要将该文件复制到我们的项目中。 我们本可以使用已经存在的“副本捆绑资源”阶段,但我们想使其更加明确和可见:

Image for post

With that, we can access to the JSON file after building as to any other resource, through our Xcode project navigator:

这样,我们可以在构建任何其他资源之后通过Xcode项目导航器访问JSON文件:

Image for post

迅捷代码 (The Swift Code)

We are now there, back from the cryptic and mysterious lands of Python and scripting in Xcode territory, where a Swift iOS developer feels cozy.

现在,我们回到了Python神秘而神秘的领域,并且在Xcode领域编写了脚本,Swift iOS开发人员对此感到很舒服。

Our last duty is therefore to assign these defaults in the Remote Config, to make available and accessible right from the first app start. We have to enforce that this happens before any Remote Config value is accessed:

因此,我们的最后职责是在Remote Config中分配这些默认值,以便从第一个应用程序开始就立即可用和可访问。 我们必须强制这种情况在访问任何远程配置值之前发生:

We parse the JSON to convert it into the expected Dictionary format. As mentioned before, we could use the PLIST method if already created that extension file in our script:

我们解析JSON以将其转换为预期的Dictionary格式。 如前所述,如果已经在脚本中创建了扩展文件,则可以使用PLIST方法:

open func setDefaults(fromPlist fileName: String?)

奖金追踪:CI (Bonus Track: The CI)

Everything until now is delightful, but what happens with our Continuous Integration Process? In our case Travis CI takes care of building and releasing the QA and Production versions for Testflight. If, as we said before, we cannot commit the private key to authorize the script request all the previous effort would have been in vain.

到目前为止,一切都令人愉快,但是我们的持续集成流程会如何? 在我们的案例中, Travis CI负责构建和发布Testflight的质量检查和生产版本。 如前所述,如果我们不能提交私钥来授权脚本请求,那么以前所有的努力都是徒劳的。

The solution? To add it to the repo encrypted, and let Travis decrypt it before building. That way we keep it secure while mimicking the local build behaviour in our CI.

解决方案? 要将其添加到已加密的仓库中,并让Travis在构建之前对其进行解密。 这样,我们就可以在模拟CI中的本地构建行为的同时保持其安全性。

If you use Travis you can follow their guide to encrypt a file here. Just don’t forget to add python dependencies and the decryption command at .before_install phase in the travis.yml.

如果您使用Travis,则可以按照他们的指南在此处加密文件。 只是不要忘记在travis.yml中的.before_install阶段添加python依赖项和解密命令。

If you opted for Jenkins, here there is a good point to start. I am sure every continuous integration & continuous delivery platform include this capability in their toolset.

如果您选择詹金斯, 这里是一个很好的起点。 我确信每个持续集成和持续交付平台在其工具集中都包含此功能。

Bonus Track II:Android (Bonus Track II: The Android)

My colleague Paulina Strychacz extended the script when implementing this feature on Android, so it directly parses the defaults into an XML file. Since the Android Remote Config SDK accepts that format when setting the defaults, they skip the intermediate step of parsing the JSON content:

我的同事Paulina Strychacz在Android上实现此功能时扩展了该脚本,因此它可以直接将默认值解析为XML文件。 由于Android Remote Config SDK会在设置默认值时接受该格式,因此它们跳过了解析JSON内容的中间步骤:

结论 (The Conclusion)

With this article we proved how we can make use of different technologies to extend the potential of a known platform as Remote Config. We:

通过本文,我们证明了如何利用各种技术来扩展已知平台Remote Config的潜力。 我们:

  • Created a Python script to download and parse the default values included in our Remote Config dashboard.

    创建了一个Python脚本来下载和解析Remote Config仪表板中包含的默认值。
  • Showed how we can call that script in a Xcode Build Phase so we have them accessible from our codebase.

    展示了如何在Xcode构建阶段中调用该脚本,从而使我们可以从代码库中访问它们。
  • Set these defaults in our app Swift codebase through the Remote Config SDK.

    通过Remote Config SDK在我们的应用Swift代码库中设置这些默认值。
  • Encrypted the private Key so it can be used in the CI.

    加密私钥,以便可以在CI中使用它。

I hope you can use this approach in your own apps, and please do not hesitate to add a comment if you have suggestions or questions.

希望您可以在自己的应用中使用此方法,如果有建议或问题,请不要犹豫添加评论。

I would like to thank Paul Hackenberger for this idea, and Paulina Strychacz for the convenient improvements on the Android side.

我要感谢Paul Hackenberger的这个想法,以及Paulina Strychacz的Android方面的便利改进。

Happy scripting!

脚本编写愉快!

You can access to the script here.

您可以在此处访问脚本。

翻译自: https://medium.com/axel-springer-tech/retrieve-default-remote-config-values-at-compile-time-efa65cb2e360

无法检索.net 编译设置

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Protobuf编译是指将.proto文件编译成可用的代码文件。在Windows下,可以使用protoc.exe执行以下命令来进行编译: ``` protoc --cpp_out=. example.proto ``` 这将生成example.proto.h和example.proto.cc文件,其中example.proto是你的.proto文件的名称。\[1\] 编译.proto文件的指令格式为: ``` protoc \[--proto_path=IMPORT_PATH\] --cpp_out=DST_DIR file.proto ``` 其中: - --proto_path:指定.proto文件的检索路径,可以多次指定。如果不指定,默认在当前文件夹下检索。 - --cpp_out:指定编译后的文件类型为C++。 - DST_DIR:指定生成文件的存放路径。 - file.proto:指定要编译的.proto文件(在--proto_path路径下的文件)。\[2\] 通过以上命令进行编译后,你将得到可以在C++代码中使用的protobuf相关文件,可以根据需要进行序列化和反序列化操作。\[3\] #### 引用[.reference_title] - *1* [protobuf 编译及使用](https://blog.csdn.net/WeinKee/article/details/105152620)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [【Protobuf速成指南】.proto文件的编写与编译](https://blog.csdn.net/whc18858/article/details/131064187)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值