改进 2.3.1

改进 2.3.1

测试已测试
Lang语言 Obj-CObjective C
许可证 NOASSERTION
发布上次发布2019年9月

Facebook, Inc.Nikita Lutsenko 维护。



改进 2.3.1

改进

改进是一种简单的方式,可以对 iOS 应用进行微调。 Build Status

Tweaks

为何

改进应用程序的最佳方式是每天都使用它。即使是那些可以提前测试出的想法——例如使用 Origami ——在实际应用程序中应用这些想法仍可能需要一些时间。

偶尔,第一次尝试就可能是完美的。有时,这个想法根本不起作用。但通常,它只需要一些小的调整。这正是改进用武之地。改进使得这些小调整变得容易:无需代码更改和电脑,您就可以尝试不同的选项并决定哪个效果最好。

一些最有用的调整参数包括动画时间、速度阈值、颜色和物理常数。在 Facebook,我们还在开发期间临时禁用新功能。这样,相关的设计师和工程师可以在他们的设备上启用它,而不会妨碍其他人测试应用程序。

改进对建造 Paper 至关重要。我们希望它对您的应用也很有用。

使用方法

每个可配置的值称为调整项。有多种方法设置它们,可以在 FBTweakInline.h 中找到。

创建调整项的最简单方法是使用 FBTweakValue 替换一个常量。

CGFloat animationDuration = FBTweakValue(@"Category", @"Group", @"Duration", 0.5);

前三个参数是调整项的列表位置和名称,最后一个参数是默认值。可以为默认值传递多种类型的值:布尔值、数字或字符串。

if (FBTweakValue(@"Category", @"Feature", @"Enabled", YES)) {
  label.text = FBTweakValue(@"Category", @"Group", @"Text", @"Tweaks example.");
}

在发布构建中,FBTweakValue 宏展开为仅仅是默认值,因此没有性能影响。但在调试构建中,它将检索调整项的最新值。

您还可以传递第五个参数,这将限制调整项的可能值。第五个参数可以是数组、字典或 FBTweakNumericRange。如果是字典,则值应显示在列表选项中的字符串。数组将显示值的 description 作为选项。(注意,您必须将数组和字典字面量用一对额外的大括号括起来。)

self.initialMode = FBTweakValue(@"Header", @"Initial", @"Mode", @(FBSimpleMode), (@{ @(FBSimpleMode) : @"Simple", @(FBAdvancedMode) : @"Advanced" }));

对于数值调整项(NSIntegerCGFloat 等),您可以传递两个参数,这些参数将值限制为 FBTweakNumericRange

self.red = FBTweakValue(@"Header", @"Colors", @"Red", 0.5, 0.0, 1.0);

绑定

要使调整项实时更新,可以使用 FBTweakBind

FBTweakBind(self.headerView, alpha, @"Main Screen", @"Header", @"Alpha", 0.85);

第一个参数是绑定到的对象,第二个参数是属性。每当调整项被更改时,self.headerViewalpha 属性便会更新以匹配。一些更多示例

FBTweakBind(audioPlayer, volume, @"Player", @"Audio", @"Volume", 0.9);
FBTweakBind(webView.scrollView, scrollEnabled, @"Browser", @"Scrolling", @"Enabled", YES);

FBTweakValue 类似,在发布构建中 FBTweakBind 展开为仅仅是设置属性为默认值。

动作

动作允许您在选中调整项时运行一个(全局)块。要创建一个,请使用 FBTweakAction

FBTweakAction(@"Player", @"Audio", @"Volume", ^{
  NSLog(@"Action selected.");
});

前三个参数是标准的调整项列出信息,最后一个参数是要调用的块。您可以在任何范围内使用 FBTweakAction,但块必须是全局的:它不能依赖于任何局部或实例变量(它不知道应该调整哪个对象)。

动作对于启动调试 UI、检查更新,或者(如果您创建了一个有意崩溃的动作)测试崩溃报告非常有用。

调整UI

要配置你的调整,你需要一种方式来显示配置UI。为此有两个选择

  • 传统上,调整通过摇晃手机激活。要使用此方法,只需将你的根 UIWindow 替换为 FBTweakShakeWindow。如果你在使用Storyboards,可以覆盖应用代理中的 -window
- (UIWindow *)window
{
  if (!_window) {
    _window = [[FBTweakShakeWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
  }

  return _window;
}
  • 你可以在应用的任何地方呈现 FBTweakViewController。确保将激活UI限制在调试构建中!
- (void)showTweaks {
   FBTweakViewController *tweakVC = [[FBTweakViewController alloc] initWithStore:[FBTweakStore sharedInstance]];
   tweakVC.tweaksDelegate = self;
   // Assuming this is in the app delegate
   [self.window.rootViewController presentViewController:tweakVC animated:YES completion:nil];
}

- (void)tweakViewControllerPressedDone:(FBTweakViewController *)tweakViewController {
   [tweakViewController dismissViewControllerAnimated:YES completion:NULL];
}

调整UI关闭通知

另外,当调整UI关闭时,你可以注册你的通知中心来监听 FBTweakShakeViewControllerDidDismissNotification,这可以通过导入 FBTweakViewController.h 后使用

高级

你还可以访问上述宏所组成的对象。这在更复杂的场景中很有用,例如调整C结构体成员。

例如,手动创建一个调整

FBTweak *tweak = [[FBTweak alloc] initWithIdentifier:@"com.tweaks.example.advanced"];
tweak.name = @"Advanced Settings";
tweak.defaultValue = @NO;

FBTweakStore *store = [FBTweakStore sharedInstance];
FBTweakCategory *category = [[FBTweakCategory alloc] initWithName:@"Settings"];
[store addTweakCategory:category];
FBTweakCollection *collection = [[FBTweakCollection alloc] initWithName:@"Enable"];
[category addTweakCollection:collection];
[collection addTweak:tweak];

[tweak addObserver:self];

然后,你可以侦听调整何时发生变化

- (void)tweakDidChange:(FBTweak *)tweak
{
  self.advancedSettingsEnabled = ![tweak.currentValue boolValue];
}

此外,你有实现可选方法 tweakWillChange: 的能力,以便处理调整的前一个值

- (void)tweakWillChange:(FBTweak *)tweak
{
  NSLog(@"%@", tweak.currentValue); // Here current value is the previous value of the tweak
}

要覆盖调整启用时的行为,可以定义 FB_TWEAK_ENABLED 宏。建议在提交到App Store时避免包含它们。

从Swift项目中使用

Khan Academy的Swift项目 SwiftTweaks 专为Swift设计,可能更适合Swift项目。

调整可以从Swift项目中使用。在这种情况下,定义在 FBTweakInline.h 中的方便快捷宏不可用,因此调整需要以程序方式创建,类似于以下示例

let tweak = FBTweak(identifier: "com.tweaks.example.advanced")
tweak.name = "Advanced settings"
tweak.defaultValue = false

let collection = FBTweakCollection(name: "Enable");
collection.addTweak(tweak)
        
let category = FBTweakCategory(name: "Settings")
category.addTweakCollection(collection);
        
let store = FBTweakStore.sharedInstance()
store.addTweakCategory(category)

tweak.addObserver(self)

设置调整后,你可以侦听它何时发生变化

func tweakDidChange(tweak: FBTweak!)
{
    self.advancedSettingsEnabled = tweak.currentValue as Bool;
}

工作原理

在调试构建中,修改宏使用 __attribute__((section)) 静态存储关于每个修改的数据在 mach-o 的 __FBTweak 部分。修改在启动时加载数据,并从 NSUserDefaults 加载最新值。

在发布版本中,宏仅展开为默认值。二进制中不包含任何其他内容。

安装

有两种选择

  1. 修改在 CocoaPods 中作为 Tweaks 提供。 (如果您有自定义 Xcode 配置的问题,这篇评论可能有所帮助。)
  2. 手动将 FBTweak/ 中的文件添加到您的 Xcode 项目中。略简单,但更新也是手动的。

修改需要 iOS 6 或更高版本。

还有一个示例项目可供使用。要使用它,请确保打开 FBTweakExample.xcworkspace(而不是 .xcodeproj),以便正确构建依赖项。

贡献

请参阅 CONTRIBUTING 文件了解如何帮助。

许可

修改采用 BSD 许可。我们还提供额外的专利许可。