1

假设你需要对一系列不同的 Objects 进行一系列复杂的配置。这个配置可以是NSString,比如服务的服务器地址,NSNumber,比如超时时间等等。我想施加以下约束:

  • 配置不得对用户可见和/或不可编辑,因此应用程序包中的 plist 不是可接受的解决方案
  • 我需要为调试、AdHoc 或发布目标设置不同的配置值(我可能会通过一系列#ifdef 来实现这一点,但我是为了完整性而写的)
  • 我要配置的所有对象都属于静态库,我想从使用此静态库的代码中注入配置(注入是斜体,作为我个人对依赖注入的提示)

我的问题是:实现这一目标的最佳方法是什么?你有没有遇到过这样的问题?你是怎么解决的?

4

6 回答 6

2

利用Xcode 构建系统。您可以拥有任何构建配置(调试、发布等)和目标组合的Xcode 配置文件。

这些文件支持继承以简化共享配置。没有单一的方法来定义选项。一个简单的方法是使用GCC_PREPROCESSOR_DEFINITIONSorCFLAGS或您的编译器将采用的任何内容。

TargetX.xcconfig

GCC_PREPROCESSOR_DEFINITIONS = STAGE=2 SERVER_URL='www.wuonm.com'

使用配置的值来构建所需的对象是相当简单NSStringNSNumber。提示:您将需要某种字符串化

它与使用非常相似,但恕我直言,如果您花一些时间了解文件的工作原理#define,它会更加简洁和结构化。xcconfig

于 2012-06-01T09:35:52.073 回答
0

要求第一次使用时,存在互联网连接并通过 HTTPS 下载您的配置并将其保存在内存中(如果需要,可以加密)。

然后利用 iOS 中的钥匙串,将您的配置作为字符串存储在那里(本质上是序列化它)。

NSString *serializedConfig = ...;
[keychain setObject:serializedConfig  forKey@"MyConfig"];

在后续使用中,检索存储在钥匙串中的配置:

NSString *serializedConfig = [keychain objectForKey:@"MyConfig"];

您可以在 Apple Docs 站点上找到钥匙串包装器和文档。

于 2012-06-01T11:39:42.880 回答
0

这篇文章有很多问题:

  1. 为什么您的输入配置需要这种级别的保护?
  2. 是您不希望用户能够修改您的配置,还是您根本不希望他们能够知道它?
  3. 如果您相信 SW 无法保护 SW 的理论,那么您真的愿意让自己经历多大程度的痛苦,以便让黑客经历足够的痛苦,他们不想破解您的 SW(因为让我们面对现实吧,这就是您的全部真的会得到,请参阅我上面关于加密的评论)
  4. 我有点同意从互联网上获取您的配置,但这仅适用于您希望存在互联网功能以使用您的应用程序的情况。如果您这样做并且还需要某种程度的保护,那么您将不得不使用一些安全协议(如 SSL)来下载它。
  5. 如果您真的希望您的应用程序能够在本地使用(没有互联网访问权限),那么我会说您的配置的真正安全性是不可能的,因为您不控制操作系统,您不控制您的软件运行的硬件, ETC...
  6. 将您的应用程序放在 iPhone 上可能意味着您希望获得相当大的下载量。这意味着触摸它并可能对其产生裂缝的手的数量也很大。在这种情况下获得安全性的唯一方法(实际上没有软件),就是让破解它的价值让你的配置不值那么多钱。如果价值低,那么没有黑客会愿意尝试破解它!
于 2012-05-30T15:59:58.590 回答
0

我在不同类中使用的服务器 URL 和常量数字(如颜色、大小和几乎任何需要轻松更改的配置)中遇到了同样的问题。我找到的最佳解决方案是创建一个像 Constants.h 这样的头文件,这个头文件的内容是:

#define MAX_DIST 1000
#define MIN_DIST 300
#define ANIMATION_DURATION 0.010
#define PIXEL_MOVES 7
#define SENSITIVITY 14
#define VIEW_ANGLE 30 //Range of vision divided by 2
#define RAD_POS_X 415
#define RAD_POS_Y 15
#define BUTTON_VIEW_WIDTH PIXEL_MOVES*360
#define SCREEN_HEIGHT 480
#define BUTTON_WIDTH_CLOSE 180
#define BUTTON_HEIGHT_CLOSE 100
#define BUTTON_WIDTH_MEDIUM 100
#define BUTTON_HEIGHT_MEDIUM 60
#define BUTTON_WIDTH_FAR 60
#define BUTTON_HEIGHT_FAR 40
#define BUTTON_Y_POSITION_CLOSE 200
#define BUTTON_Y_POSITION_MEDIUM 135
#define BUTTON_Y_POSITION_FAR 90
#define SERVICE_URL @"http://my.server.com/SoapServer/SoapServiceWS"//

您甚至可以定义常用功能,例如

#define DEGREES_TO_RADIANS(__ANGLE__) ((__ANGLE__) / 180.0 * M_PI)

通过这种方式,我能够从一个文件配置我的应用程序的各个方面,并且您可以像您说的那样使用#ifdef 来管理不同的编译。当然,您必须在需要访问这些常量的任何类中导入文件 Constants.h。

于 2012-05-30T16:18:37.963 回答
0

您的静态库应该提供一些接口来设置将在运行时设置的当前配置。

SetCurrentConfiguration(Configuration config);

然后“客户端”可以在运行时使用所需的配置对其进行配置。第二步是从指定的源加载配置,比如说 xml 文件并通过上面的方法将其注入静态库。

如果您不希望用户修改配置文件,您可以使用某种加密,然后即时解密。

于 2012-05-31T15:47:07.913 回答
0

如果这些值对于每个构建配置都是常量,为什么不将它们作为常量放在代码中呢?如果它们是因配置而异的常量,我真的不明白为什么需要将这些设置外部化。使用在私有标头中声明的这些常量,您对设置的 ifdef 选择将同样有效(并且更快)。

如果这些设置在应用程序运行期间以某种方式发生变化(不是从构建到构建,而是在运行应用程序的单个构建的范围内),那么将这些设置外部化是合适的。

于 2012-05-25T14:16:52.693 回答