flip_the_switch 0.4.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +4 -1
- data/.travis.yml +3 -1
- data/CHANGELOG.md +10 -0
- data/Classes/FlipTheSwitch/Shared/FTSFeature.h +11 -0
- data/Classes/FlipTheSwitch/Shared/FTSFeature.m +67 -0
- data/Classes/FlipTheSwitch/Shared/FTSFlipTheSwitch.h +21 -0
- data/Classes/FlipTheSwitch/Shared/FTSFlipTheSwitch.m +144 -0
- data/Classes/FlipTheSwitch/iOS/FTSFeatureCell.h +17 -0
- data/Classes/FlipTheSwitch/iOS/FTSFeatureCell.m +12 -0
- data/Classes/FlipTheSwitch/iOS/FTSFeatureConfigurationViewController.h +5 -0
- data/Classes/FlipTheSwitch/iOS/FTSFeatureConfigurationViewController.m +142 -0
- data/Classes/FlipTheSwitch/iOS/FTSFeatureDescriptionLabel.h +5 -0
- data/Classes/FlipTheSwitch/iOS/FTSFeatureDescriptionLabel.m +13 -0
- data/Example/Colors-OSX/AppDelegate.h +7 -0
- data/Example/Colors-OSX/AppDelegate.m +17 -0
- data/Example/Colors-OSX/Base.lproj/Main.storyboard +744 -0
- data/Example/Colors-OSX/ColoredViews/GreenView.h +5 -0
- data/Example/Colors-OSX/ColoredViews/GreenView.m +12 -0
- data/Example/Colors-OSX/ColoredViews/PurpleView.h +5 -0
- data/Example/Colors-OSX/ColoredViews/PurpleView.m +12 -0
- data/Example/Colors-OSX/ColoredViews/RedView.h +5 -0
- data/Example/Colors-OSX/ColoredViews/RedView.m +12 -0
- data/Example/Colors-OSX/ColoredViews/YellowView.h +5 -0
- data/Example/Colors-OSX/ColoredViews/YellowView.m +12 -0
- data/Example/Colors-OSX/FTSFlipTheSwitch+Features.h +45 -0
- data/Example/Colors-OSX/FTSFlipTheSwitch+Features.m +165 -0
- data/Example/Colors-OSX/Features.plist +39 -0
- data/Example/Colors-OSX/Images.xcassets/AppIcon.appiconset/Contents.json +58 -0
- data/Example/Colors-OSX/Info.plist +32 -0
- data/Example/Colors-OSX/Settings.bundle/Features.plist +59 -0
- data/Example/Colors-OSX/Settings.bundle/Root.plist +23 -0
- data/Example/Colors-OSX/ViewController.h +14 -0
- data/Example/Colors-OSX/ViewController.m +152 -0
- data/Example/Colors-OSX/main.m +5 -0
- data/Example/Colors-iOS/Base.lproj/Main.storyboard +111 -0
- data/Example/Colors-iOS/Colors-iOS-Info.plist +2 -2
- data/Example/Colors-iOS/FTSFlipTheSwitch+Features.h +45 -0
- data/Example/Colors-iOS/FTSFlipTheSwitch+Features.m +165 -0
- data/Example/Colors-iOS/Images.xcassets/AppIcon.appiconset/Contents.json +15 -0
- data/Example/Colors-iOS/ViewControlleriOS.m +55 -20
- data/Example/Colors.xcodeproj/project.pbxproj +273 -25
- data/Example/Colors.xcodeproj/xcshareddata/xcschemes/Colors-OSX.xcscheme +115 -0
- data/Example/Colors.xcodeproj/xcshareddata/xcschemes/Colors-iOS.xcscheme +9 -15
- data/Example/FTSFlipTheSwitch+Features.h +45 -0
- data/Example/FTSFlipTheSwitch+Features.m +165 -0
- data/Example/Features.plist +39 -0
- data/Example/Gemfile +4 -0
- data/Example/Podfile +11 -2
- data/Example/README.md +13 -0
- data/Example/Rakefile +5 -1
- data/Example/features.json +23 -0
- data/FlipTheSwitch.podspec +9 -4
- data/Gemfile +2 -1
- data/README.md +101 -21
- data/Resources/FlipTheSwitch/FlipTheSwitch.storyboard +208 -0
- data/Tests/FlipTheSwitchSpec-iOS/Features.plist +6 -1
- data/Tests/{FlipTheSwitchSpec-Mac/Features.plist → FlipTheSwitchSpec-iOS/OtherFeatures.plist} +5 -2
- data/Tests/FlipTheSwitchSpec.xcodeproj/project.pbxproj +101 -38
- data/Tests/FlipTheSwitchSpec.xcodeproj/xcshareddata/xcschemes/FlipTheSwitchSpec-Mac.xcscheme +9 -7
- data/Tests/FlipTheSwitchSpec.xcodeproj/xcshareddata/xcschemes/FlipTheSwitchSpec-iOS.xcscheme +9 -7
- data/Tests/Rakefile +1 -1
- data/Tests/Spec/Classes/FlipTheSwitch/FlipTheSwitchSpec.m +134 -28
- data/flip_the_switch.gemspec +2 -1
- data/images/feature_configuration_screen.png +0 -0
- data/lib/flip_the_switch.rb +2 -0
- data/lib/flip_the_switch/cli.rb +16 -24
- data/lib/flip_the_switch/environment.rb +11 -0
- data/lib/flip_the_switch/feature.rb +11 -0
- data/lib/flip_the_switch/generator/base.rb +3 -3
- data/lib/flip_the_switch/generator/category.rb +13 -5
- data/lib/flip_the_switch/generator/header.h.erb +15 -8
- data/lib/flip_the_switch/generator/implementation.m.erb +36 -12
- data/lib/flip_the_switch/generator/plist.rb +19 -1
- data/lib/flip_the_switch/generator/settings.rb +6 -6
- data/lib/flip_the_switch/reader/features.rb +136 -22
- data/spec/flip_the_switch/cli_spec.rb +12 -12
- data/spec/flip_the_switch/environment_spec.rb +20 -0
- data/spec/flip_the_switch/feature_spec.rb +20 -0
- data/spec/flip_the_switch/generator/category_spec.rb +14 -8
- data/spec/flip_the_switch/generator/plist_spec.rb +23 -7
- data/spec/flip_the_switch/generator/settings_spec.rb +6 -3
- data/spec/flip_the_switch/reader/defaults_spec.rb +0 -18
- data/spec/flip_the_switch/reader/features_spec.rb +74 -17
- data/spec/resources/ExpectedFeatures.plist +10 -2
- data/spec/resources/expected_header.h +8 -3
- data/spec/resources/expected_implementation.m +37 -10
- data/spec/resources/invalid_layout/features.json +7 -0
- data/spec/resources/invalid_type/features.json +23 -0
- data/spec/resources/real/features.json +38 -0
- data/tmp/.keep +0 -0
- metadata +74 -16
- data/Classes/FlipTheSwitch/FlipTheSwitch.h +0 -9
- data/Classes/FlipTheSwitch/FlipTheSwitch.m +0 -88
- data/Example/Colors-iOS/Base.lproj/Main_iPhone.storyboard +0 -76
- data/Example/features.yml +0 -3
- data/Tests/Spec/Helpers/GcovTestObserver.h +0 -4
- data/Tests/Spec/Helpers/GcovTestObserver.m +0 -12
- data/spec/resources/invalid_layout/features.yml +0 -4
- data/spec/resources/invalid_type/features.yml +0 -7
- data/spec/resources/real/features.yml +0 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4e4c3d08117d7df04e9f0b072c46ceaa37677bae
|
4
|
+
data.tar.gz: 129fd88d8381ebc2caac41d0cc28a52640043d2c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: aeb03d159b4a890318eea4976566d192c15c780558ec15eb2267047fd33f23891126acd287052d58f1a308fbd4414a8a19ec99fdcfb6107b30742f73940c02f0
|
7
|
+
data.tar.gz: 7120397022f1507790cd58763fc28fbb10fcc50d30ccf695eaeb21a7687474bd788c16bdb281b2d68accfc26eb01d375605955f32fb51bc8ac7eb61d42d22bb5
|
data/.gitignore
CHANGED
@@ -41,7 +41,7 @@ profile
|
|
41
41
|
|
42
42
|
####
|
43
43
|
# Xcode temporary files that should never be committed
|
44
|
-
#
|
44
|
+
#
|
45
45
|
# NB: NIB/XIB files still exist even on Storyboard projects, so we want this...
|
46
46
|
|
47
47
|
*~.nib
|
@@ -139,6 +139,9 @@ xcuserdata
|
|
139
139
|
|
140
140
|
*.moved-aside
|
141
141
|
|
142
|
+
####
|
143
|
+
# AppCode
|
144
|
+
.idea/
|
142
145
|
|
143
146
|
####
|
144
147
|
# UNKNOWN: recommended by others, but I can't discover what these files are
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
# 1.0.0 / 2015-10-15
|
2
|
+
|
3
|
+
* [ENHANCEMENT] Using JSON instead of YAML for features
|
4
|
+
* [ENHANCEMENT] #37 Add Mac OSX Example Project
|
5
|
+
* [FEATURE] #36 Possibility to reset all features button (according to original plist at once)
|
6
|
+
* [FEATURE] #24 Adding reset to defaults functionality
|
7
|
+
* [FEATURE] #22 Adding support for subfeature
|
8
|
+
* [FEATURE] #21 Notifications on Feature Status
|
9
|
+
* [FEATURE] #20 Possibility to add description for feature flags
|
10
|
+
|
1
11
|
# 0.4.0 / 2014-07-16
|
2
12
|
|
3
13
|
* [FEATURE] #17 Use environments for feature states
|
@@ -0,0 +1,11 @@
|
|
1
|
+
@import Foundation;
|
2
|
+
|
3
|
+
@interface FTSFeature : NSObject
|
4
|
+
@property (nonatomic, readonly) NSString *name;
|
5
|
+
@property (nonatomic, readonly) NSString *featureDescription;
|
6
|
+
@property (nonatomic, readonly) BOOL enabled;
|
7
|
+
|
8
|
+
- (id)init NS_UNAVAILABLE;
|
9
|
+
- (instancetype)initWithName:(NSString *)name enabled:(BOOL)enabled featureDescription:(NSString *)featureDescription;
|
10
|
+
|
11
|
+
@end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
#import "FTSFeature.h"
|
2
|
+
|
3
|
+
@implementation FTSFeature
|
4
|
+
|
5
|
+
- (instancetype)initWithName:(NSString *)name enabled:(BOOL)enabled featureDescription:(NSString *)featureDescription
|
6
|
+
{
|
7
|
+
self = [super init];
|
8
|
+
if (self) {
|
9
|
+
NSParameterAssert(name);
|
10
|
+
_name = name;
|
11
|
+
_featureDescription = featureDescription;
|
12
|
+
_enabled = enabled;
|
13
|
+
}
|
14
|
+
return self;
|
15
|
+
}
|
16
|
+
|
17
|
+
- (BOOL)isEqual:(id)other
|
18
|
+
{
|
19
|
+
if (other == self) {
|
20
|
+
return YES;
|
21
|
+
}
|
22
|
+
if (!other || ![[other class] isEqual:[self class]]) {
|
23
|
+
return NO;
|
24
|
+
}
|
25
|
+
|
26
|
+
return [self isEqualToFeature:other];
|
27
|
+
}
|
28
|
+
|
29
|
+
- (BOOL)isEqualToFeature:(FTSFeature *)feature
|
30
|
+
{
|
31
|
+
if (self == feature) {
|
32
|
+
return YES;
|
33
|
+
}
|
34
|
+
if (feature == nil) {
|
35
|
+
return NO;
|
36
|
+
}
|
37
|
+
if (self.name != feature.name && ![self.name isEqualToString:feature.name]) {
|
38
|
+
return NO;
|
39
|
+
}
|
40
|
+
if (self.featureDescription != feature.featureDescription && ![self.featureDescription isEqualToString:feature.featureDescription]) {
|
41
|
+
return NO;
|
42
|
+
}
|
43
|
+
if (self.enabled != feature.enabled) {
|
44
|
+
return NO;
|
45
|
+
}
|
46
|
+
return YES;
|
47
|
+
}
|
48
|
+
|
49
|
+
- (NSUInteger)hash
|
50
|
+
{
|
51
|
+
NSUInteger hash = [self.name hash];
|
52
|
+
hash = hash * 31u + [self.featureDescription hash];
|
53
|
+
hash = hash * 31u + self.enabled;
|
54
|
+
return hash;
|
55
|
+
}
|
56
|
+
|
57
|
+
- (NSString *)description
|
58
|
+
{
|
59
|
+
NSMutableString *description = [NSMutableString stringWithFormat:@"<%@: ", NSStringFromClass([self class])];
|
60
|
+
[description appendFormat:@"self.name=%@", self.name];
|
61
|
+
[description appendFormat:@", self.featureDescription=%@", self.featureDescription];
|
62
|
+
[description appendFormat:@", self.enabled=%d", self.enabled];
|
63
|
+
[description appendString:@">"];
|
64
|
+
return description;
|
65
|
+
}
|
66
|
+
|
67
|
+
@end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
@import Foundation;
|
2
|
+
|
3
|
+
#import "FTSFeature.h"
|
4
|
+
|
5
|
+
extern NSString *const FTSFeatureStatusChangedNotification;
|
6
|
+
extern NSString *const FTSFeatureStatusChangedNotificationFeatureKey;
|
7
|
+
extern NSString *const FTSFeatureStatusChangedNotificationEnabledKey;
|
8
|
+
extern NSString *const FTSFeaturePlistNameKey;
|
9
|
+
|
10
|
+
@interface FTSFlipTheSwitch : NSObject
|
11
|
+
- (instancetype)init NS_UNAVAILABLE;
|
12
|
+
+ (instancetype)sharedInstance;
|
13
|
+
|
14
|
+
- (NSArray *)features;
|
15
|
+
- (BOOL)isFeatureEnabled:(NSString *)feature;
|
16
|
+
- (void)enableFeature:(NSString *)feature;
|
17
|
+
- (void)disableFeature:(NSString *)feature;
|
18
|
+
- (void)setFeature:(NSString *)feature enabled:(BOOL)enabled;
|
19
|
+
- (void)resetFeature:(NSString *)feature;
|
20
|
+
- (void)resetAllFeatures;
|
21
|
+
@end
|
@@ -0,0 +1,144 @@
|
|
1
|
+
#import "FTSFlipTheSwitch.h"
|
2
|
+
|
3
|
+
NSString *const FTSFeatureStatusChangedNotification = @"FTSFeatureStatusChangedNotification";
|
4
|
+
NSString *const FTSFeatureStatusChangedNotificationFeatureKey = @"FTSFeatureStatusChangedNotificationFeatureKey";
|
5
|
+
NSString *const FTSFeatureStatusChangedNotificationEnabledKey = @"FTSFeatureStatusChangedNotificationEnabledKey";
|
6
|
+
NSString *const FTSFeaturePlistNameKey = @"FTSFeaturePlistNameKey";
|
7
|
+
|
8
|
+
|
9
|
+
@interface FTSFlipTheSwitch ()
|
10
|
+
@property (nonatomic, readonly) NSUserDefaults *userDefaults;
|
11
|
+
@property (nonatomic, readonly) NSBundle *bundle;
|
12
|
+
@property (nonatomic, readonly) NSNotificationCenter *notificationCenter;
|
13
|
+
@end
|
14
|
+
|
15
|
+
@implementation FTSFlipTheSwitch {
|
16
|
+
NSDictionary *_plistEnabledFeatures;
|
17
|
+
}
|
18
|
+
|
19
|
+
#pragma mark - Singleton
|
20
|
+
|
21
|
+
+ (instancetype)sharedInstance
|
22
|
+
{
|
23
|
+
static FTSFlipTheSwitch *sharedInstance;
|
24
|
+
static dispatch_once_t once;
|
25
|
+
dispatch_once(&once, ^{
|
26
|
+
sharedInstance = [[self alloc] initWithUserDefaults:[NSUserDefaults standardUserDefaults]
|
27
|
+
bundle:[NSBundle mainBundle]
|
28
|
+
notificationCenter:[NSNotificationCenter defaultCenter]];
|
29
|
+
});
|
30
|
+
return sharedInstance;
|
31
|
+
}
|
32
|
+
|
33
|
+
#pragma mark - Initialization
|
34
|
+
|
35
|
+
- (instancetype)initWithUserDefaults:(NSUserDefaults *)userDefaults
|
36
|
+
bundle:(NSBundle *)bundle
|
37
|
+
notificationCenter:(NSNotificationCenter *)notificationCenter
|
38
|
+
{
|
39
|
+
self = [super init];
|
40
|
+
if (self) {
|
41
|
+
NSParameterAssert(userDefaults);
|
42
|
+
NSParameterAssert(bundle);
|
43
|
+
NSParameterAssert(notificationCenter);
|
44
|
+
_userDefaults = userDefaults;
|
45
|
+
_bundle = bundle;
|
46
|
+
_notificationCenter = notificationCenter;
|
47
|
+
}
|
48
|
+
return self;
|
49
|
+
}
|
50
|
+
|
51
|
+
#pragma mark - Public
|
52
|
+
|
53
|
+
- (NSArray *)features
|
54
|
+
{
|
55
|
+
NSMutableArray *featureArray = [NSMutableArray array];
|
56
|
+
for (NSString *featureName in [self plistEnabledFeatures]) {
|
57
|
+
FTSFeature *feature = [[FTSFeature alloc] initWithName:featureName
|
58
|
+
enabled:[self isFeatureEnabled:featureName]
|
59
|
+
featureDescription:[self plistEnabledFeatures][featureName][@"description"]];
|
60
|
+
[featureArray addObject:feature];
|
61
|
+
}
|
62
|
+
return [featureArray copy];
|
63
|
+
}
|
64
|
+
|
65
|
+
- (BOOL)isFeatureEnabled:(NSString *)feature
|
66
|
+
{
|
67
|
+
NSNumber *userEnabledFeature = [self.userDefaults objectForKey:[self userKeyForFeature:feature]];
|
68
|
+
if (userEnabledFeature) {
|
69
|
+
return [userEnabledFeature boolValue];
|
70
|
+
} else {
|
71
|
+
return [[self plistEnabledFeatures][feature][@"enabled"] boolValue];
|
72
|
+
}
|
73
|
+
}
|
74
|
+
|
75
|
+
- (void)enableFeature:(NSString *)feature
|
76
|
+
{
|
77
|
+
[self setFeature:feature enabled:YES];
|
78
|
+
}
|
79
|
+
|
80
|
+
- (void)disableFeature:(NSString *)feature
|
81
|
+
{
|
82
|
+
[self setFeature:feature enabled:NO];
|
83
|
+
}
|
84
|
+
|
85
|
+
- (void)setFeature:(NSString *)feature enabled:(BOOL)enabled
|
86
|
+
{
|
87
|
+
if (![self isFeatureEnabled:feature] == enabled) {
|
88
|
+
[self.userDefaults setObject:@(enabled) forKey:[self userKeyForFeature:feature]];
|
89
|
+
[self.userDefaults synchronize];
|
90
|
+
[self.notificationCenter postNotification:[self statusChangeNotificationForFeature:feature
|
91
|
+
enabled:enabled]];
|
92
|
+
}
|
93
|
+
}
|
94
|
+
|
95
|
+
- (void)resetFeature:(NSString *)feature
|
96
|
+
{
|
97
|
+
[self.userDefaults removeObjectForKey:[self userKeyForFeature:feature]];
|
98
|
+
[self.userDefaults synchronize];
|
99
|
+
[self.notificationCenter postNotification:[self statusChangeNotificationForFeature:feature
|
100
|
+
enabled:[self isFeatureEnabled:feature]]];
|
101
|
+
}
|
102
|
+
|
103
|
+
- (void)resetAllFeatures
|
104
|
+
{
|
105
|
+
for (NSString *featureName in [self plistEnabledFeatures]) {
|
106
|
+
[self resetFeature:featureName];
|
107
|
+
}
|
108
|
+
}
|
109
|
+
|
110
|
+
#pragma mark - Private
|
111
|
+
|
112
|
+
- (NSString *)userKeyForFeature:(NSString *)feature
|
113
|
+
{
|
114
|
+
return [NSString stringWithFormat:@"FTS_FEATURE_%@", feature];
|
115
|
+
}
|
116
|
+
|
117
|
+
- (NSDictionary *)plistEnabledFeatures
|
118
|
+
{
|
119
|
+
if (!_plistEnabledFeatures) {
|
120
|
+
_plistEnabledFeatures = [[NSDictionary alloc] initWithContentsOfFile:[self featurePlistPath]];
|
121
|
+
}
|
122
|
+
return _plistEnabledFeatures;
|
123
|
+
}
|
124
|
+
|
125
|
+
- (NSString *)featurePlistPath
|
126
|
+
{
|
127
|
+
NSString *plistName = [self.userDefaults objectForKey:FTSFeaturePlistNameKey];
|
128
|
+
if (plistName == nil) {
|
129
|
+
plistName = @"Features";
|
130
|
+
}
|
131
|
+
return [self.bundle pathForResource:plistName ofType:@"plist"];
|
132
|
+
}
|
133
|
+
|
134
|
+
- (NSNotification *)statusChangeNotificationForFeature:(NSString *)feature enabled:(BOOL)enabled
|
135
|
+
{
|
136
|
+
return [NSNotification notificationWithName:FTSFeatureStatusChangedNotification
|
137
|
+
object:self
|
138
|
+
userInfo:@{
|
139
|
+
FTSFeatureStatusChangedNotificationFeatureKey : feature,
|
140
|
+
FTSFeatureStatusChangedNotificationEnabledKey : @(enabled)
|
141
|
+
}];
|
142
|
+
}
|
143
|
+
|
144
|
+
@end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
@import Foundation;
|
2
|
+
@import UIKit;
|
3
|
+
|
4
|
+
@class FTSFeatureCell;
|
5
|
+
#import "FTSFeatureDescriptionLabel.h"
|
6
|
+
|
7
|
+
@protocol FlipTheSwitchCellDelegate <NSObject>
|
8
|
+
- (void)flipTheSwitchCellDidToggleFeature:(FTSFeatureCell *)cell;
|
9
|
+
@end
|
10
|
+
|
11
|
+
@interface FTSFeatureCell : UITableViewCell
|
12
|
+
@property (nonatomic, weak) IBOutlet UILabel *featureNameLabel;
|
13
|
+
@property (nonatomic, weak) IBOutlet UISwitch *toggle;
|
14
|
+
@property (nonatomic, weak) IBOutlet FTSFeatureDescriptionLabel *featureDescriptionLabel;
|
15
|
+
|
16
|
+
@property (nonatomic, weak) id<FlipTheSwitchCellDelegate> delegate;
|
17
|
+
@end
|
@@ -0,0 +1,142 @@
|
|
1
|
+
#import "FTSFeatureConfigurationViewController.h"
|
2
|
+
#import "FTSFlipTheSwitch.h"
|
3
|
+
#import "FTSFeatureCell.h"
|
4
|
+
|
5
|
+
static NSString * const FTSFeatureCellIdentifier = @"featureCell";
|
6
|
+
|
7
|
+
@interface FTSFeatureConfigurationViewController () <UITableViewDelegate, UITableViewDataSource, FlipTheSwitchCellDelegate>
|
8
|
+
@property (nonatomic) NSArray *dataSource;
|
9
|
+
@property (weak, nonatomic) IBOutlet UITableView *tableView;
|
10
|
+
|
11
|
+
@end
|
12
|
+
|
13
|
+
@implementation FTSFeatureConfigurationViewController
|
14
|
+
|
15
|
+
#pragma mark - UIViewController
|
16
|
+
|
17
|
+
- (void)viewDidLoad
|
18
|
+
{
|
19
|
+
[super viewDidLoad];
|
20
|
+
|
21
|
+
self.tableView.delegate = self;
|
22
|
+
self.tableView.dataSource = self;
|
23
|
+
[self setupDataSource];
|
24
|
+
}
|
25
|
+
|
26
|
+
#pragma mark - Actions
|
27
|
+
|
28
|
+
- (IBAction)doneButtonTapped:(id)sender
|
29
|
+
{
|
30
|
+
[self dismissViewControllerAnimated:YES completion:nil];
|
31
|
+
}
|
32
|
+
|
33
|
+
- (IBAction)resetFeatures:(UIButton *)sender {
|
34
|
+
[self resetFeatures];
|
35
|
+
}
|
36
|
+
|
37
|
+
- (void)resetFeatures{
|
38
|
+
[[FTSFlipTheSwitch sharedInstance] resetAllFeatures];
|
39
|
+
[self reloadData];
|
40
|
+
}
|
41
|
+
|
42
|
+
#pragma mark - UITableViewDataSource
|
43
|
+
|
44
|
+
- (void)reloadData
|
45
|
+
{
|
46
|
+
[self loadFeatureData];
|
47
|
+
[self.tableView reloadData];
|
48
|
+
}
|
49
|
+
|
50
|
+
- (void)setupDataSource
|
51
|
+
{
|
52
|
+
[self loadFeatureData];
|
53
|
+
}
|
54
|
+
|
55
|
+
- (void)loadFeatureData{
|
56
|
+
self.dataSource = [[FTSFlipTheSwitch sharedInstance] features];
|
57
|
+
}
|
58
|
+
|
59
|
+
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
|
60
|
+
{
|
61
|
+
return 1;
|
62
|
+
}
|
63
|
+
|
64
|
+
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
|
65
|
+
{
|
66
|
+
return [self.dataSource count];
|
67
|
+
}
|
68
|
+
|
69
|
+
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
|
70
|
+
{
|
71
|
+
return [self heightForBasicCellAtIndexPath:indexPath];
|
72
|
+
}
|
73
|
+
|
74
|
+
#pragma mark - UITableViewDelegate
|
75
|
+
|
76
|
+
- (CGFloat)heightForBasicCellAtIndexPath:(NSIndexPath *)indexPath
|
77
|
+
{
|
78
|
+
[self configureFeatureCell:self.sizingCell atIndexPath:indexPath];
|
79
|
+
return [self calculateHeightForConfiguredSizingCell:self.sizingCell];
|
80
|
+
}
|
81
|
+
|
82
|
+
- (CGFloat)calculateHeightForConfiguredSizingCell:(UITableViewCell *)sizingCell
|
83
|
+
{
|
84
|
+
sizingCell.bounds = CGRectMake(0.0f, 0.0f, CGRectGetWidth(self.tableView.frame), CGRectGetHeight(sizingCell.bounds));
|
85
|
+
[sizingCell layoutIfNeeded];
|
86
|
+
|
87
|
+
CGSize size = [sizingCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
|
88
|
+
return size.height + 1.0f; // seperator
|
89
|
+
}
|
90
|
+
|
91
|
+
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
|
92
|
+
{
|
93
|
+
return [self featureCellAtIndexPath:indexPath];
|
94
|
+
}
|
95
|
+
|
96
|
+
#pragma mark - FlipTheSwitchCellDelegate
|
97
|
+
|
98
|
+
- (void)flipTheSwitchCellDidToggleFeature:(FTSFeatureCell *)cell
|
99
|
+
{
|
100
|
+
NSUInteger index = (NSUInteger)[self.tableView indexPathForCell:cell].row;
|
101
|
+
FTSFeature *feature = self.dataSource[index];
|
102
|
+
[[FTSFlipTheSwitch sharedInstance] setFeature:feature.name
|
103
|
+
enabled:cell.toggle.on];
|
104
|
+
}
|
105
|
+
|
106
|
+
#pragma mark - Private
|
107
|
+
|
108
|
+
- (void)configureFeatureCell:(FTSFeatureCell *)cell atIndexPath:(NSIndexPath *)indexPath{
|
109
|
+
FTSFeature *feature = self.dataSource[(NSUInteger)indexPath.row];
|
110
|
+
[self presentCell:cell withFeature:feature];
|
111
|
+
}
|
112
|
+
|
113
|
+
- (FTSFeatureCell *)featureCellAtIndexPath:(NSIndexPath *)indexPath
|
114
|
+
{
|
115
|
+
FTSFeatureCell *cell = [self.tableView dequeueReusableCellWithIdentifier:FTSFeatureCellIdentifier forIndexPath:indexPath];
|
116
|
+
cell.delegate = self;
|
117
|
+
[self configureFeatureCell:cell atIndexPath:indexPath];
|
118
|
+
|
119
|
+
return cell;
|
120
|
+
}
|
121
|
+
|
122
|
+
- (void)presentCell:(FTSFeatureCell *)cell withFeature:(FTSFeature *)feature
|
123
|
+
{
|
124
|
+
cell.featureNameLabel.text = feature.name;
|
125
|
+
[cell.toggle setOn:feature.enabled animated:NO];
|
126
|
+
cell.featureDescriptionLabel.text = feature.featureDescription;
|
127
|
+
}
|
128
|
+
|
129
|
+
- (FTSFeatureCell *)sizingCell
|
130
|
+
{
|
131
|
+
static FTSFeatureCell *sizingCell = nil;
|
132
|
+
static dispatch_once_t onceToken;
|
133
|
+
dispatch_once(&onceToken, ^{
|
134
|
+
sizingCell = [self.tableView dequeueReusableCellWithIdentifier:FTSFeatureCellIdentifier];
|
135
|
+
// iOS bug fix to avoid breaking a by system added 'UIView-Encapsulated-Layout-Height' constraint
|
136
|
+
sizingCell.frame = CGRectMake(0, 0, 100, 100);
|
137
|
+
sizingCell.contentView.frame = sizingCell.frame;
|
138
|
+
});
|
139
|
+
return sizingCell;
|
140
|
+
}
|
141
|
+
|
142
|
+
@end
|