Skip to content

Commit 1fca26a

Browse files
Fix torch and streamline purchases, also add zoom during video recording (#24)
* save * this is releasable
1 parent 76909db commit 1fca26a

16 files changed

Lines changed: 209 additions & 88 deletions

RemoteCam/AppDelegate.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
1919
InAppPurchasesManager.shared().reloadProducts { (_, _) in
2020

2121
}
22-
if !InAppPurchasesManager.shared().didUserBuyRemoveiAdsFeature() &&
23-
!InAppPurchasesManager.shared().didUserBuyRemoveiAdsFeatureAndEnableVideo() {
22+
if !InAppPurchasesManager.shared().hasAdRemovalFeature() {
2423
GADMobileAds.sharedInstance().start(completionHandler: nil)
2524
}
2625

RemoteCam/BaseViewController.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,12 @@ public class iAdViewController: UIViewController {
3838
super.viewDidLoad()
3939
self.shouldHideBanner()
4040

41-
if !InAppPurchasesManager.shared().didUserBuyRemoveiAdsFeature() && !InAppPurchasesManager.shared().didUserBuyRemoveiAdsFeatureAndEnableVideo() {
41+
if !InAppPurchasesManager.shared().hasAdRemovalFeature() {
4242
self.setupAdNetwork()
4343
}
4444

4545
NotificationCenter.default.addObserver(self, selector: #selector(iAdViewController.ShouldHideAds(notification:)), name: NSNotification.Name(rawValue: Constants.removeAds()), object: nil)
46-
NotificationCenter.default.addObserver(self, selector: #selector(iAdViewController.ShouldHideAds(notification:)), name: NSNotification.Name(rawValue: Constants.removeAdsAndEnableVideo()), object: nil)
46+
NotificationCenter.default.addObserver(self, selector: #selector(iAdViewController.ShouldHideAds(notification:)), name: NSNotification.Name(rawValue: Constants.proModeAquired()), object: nil)
4747
}
4848

4949
func shouldHideBanner() {

RemoteCam/CMConfigurationsViewController.mm

Lines changed: 40 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
#import "CMConfigurationsViewController.h"
22
#import "InAppPurchasesManager.h"
33

4-
#define kiAdsFeatureInstalled NSLocalizedString(@"Ads Removed",nil);
5-
#define kiAdsRemovedANdVideoEnabledInstalled NSLocalizedString(@"Pro: All features enabled",nil);
4+
#define kiAdsFeatureInstalled NSLocalizedString(@"✅ Ads Removed",nil);
5+
#define kiAdsRemovedANdVideoEnabledInstalled NSLocalizedString(@"✅ Pro: All features enabled",nil);
6+
#define kTorchFeatureInstalled NSLocalizedString(@"✅ Torch Feature Enabled",nil);
7+
#define kVideoFeatureEnabled NSLocalizedString(@"✅ Video Feature Enabled",nil);
68
#define SendMediaToRemoteDefault @"sendMediaToRemote"
79

810
#import "AcknowledgmentsViewController.h"
@@ -93,7 +95,7 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath
9395
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
9496
InAppPurchasesManager *manager = [InAppPurchasesManager sharedManager];
9597
if ([cell isEqual:self.disableiAds]) {
96-
if ([manager didUserBuyRemoveiAdsFeature])
98+
if ([manager hasAdRemovalFeature])
9799
return;
98100
if ([[[cell textLabel] text] isEqualToString:NSLocalizedString(@"Tap to refresh from AppStore.", nil)]) {
99101
[manager reloadProductsWithHandler:^(InAppPurchasesManager *purchasesManager, NSError *error) {
@@ -115,14 +117,14 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath
115117
}];
116118
}
117119
} else if ([cell isEqual:self.disableAdsAndEnableVideoRecording]) {
118-
if ([manager didUserBuyRemoveiAdsFeatureAndEnableVideo])
120+
if ([manager hasProMode])
119121
return;
120122
if ([[[cell textLabel] text] isEqualToString:NSLocalizedString(@"Tap to refresh from AppStore.", nil)]) {
121123
[manager reloadProductsWithHandler:^(InAppPurchasesManager *purchasesManager, NSError *error) {
122-
if (!error) [self fillRestoreRemoveAdsAndEnableVideoRow];
124+
if (!error) [self fillRestoreProModeAquiredRow];
123125
}];
124126
} else {
125-
[manager userWantsToBuyFeature:RemoveAdsAndEnableVideoIdentifier withHandler:^(InAppPurchasesManager *purchasesManager, NSError *error) {
127+
[manager userWantsToBuyFeature:ProModeAquiredIdentifier withHandler:^(InAppPurchasesManager *purchasesManager, NSError *error) {
126128
if (error) {
127129
UIAlertController *alert = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"InApp Purchases:", nil) message:[error localizedDescription] preferredStyle:UIAlertControllerStyleAlert];
128130
[alert addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"Ok", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction *_Nonnull action) {
@@ -131,13 +133,30 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath
131133

132134
[self presentViewController:alert animated:TRUE completion:NULL];
133135
} else {
134-
[self fillRestoreRemoveAdsAndEnableVideoRow];
135-
[[NSNotificationCenter defaultCenter] postNotificationName:Constants.RemoveAdsAndEnableVideo object:nil];
136+
InAppPurchasesManager *manager = [InAppPurchasesManager sharedManager];
137+
138+
// Always refresh the Pro mode row
139+
[self fillRestoreProModeAquiredRow];
140+
141+
// Check each feature and refresh if now available
142+
if ([manager hasAdRemovalFeature]) {
143+
[self fillRestoreiAdsRow];
144+
}
145+
146+
if ([manager hasTorchFeature]) {
147+
[self fillRestoreEnableTorchFeatureRow];
148+
}
149+
150+
if ([manager hasVideoRecordingFeature]) {
151+
[self fillRestoreEnableVideoOnlyFeatureRow];
152+
}
153+
154+
[[NSNotificationCenter defaultCenter] postNotificationName:Constants.ProModeAquired object:nil];
136155
}
137156
}];
138157
}
139158
} else if ([cell isEqual:self.enableTorchFeature]) {
140-
if ([manager didUserBuyEnableTorchFeature])
159+
if ([manager hasTorchFeature])
141160
return;
142161
if ([[[cell textLabel] text] isEqualToString:NSLocalizedString(@"Tap to refresh from AppStore.", nil)]) {
143162
[manager reloadProductsWithHandler:^(InAppPurchasesManager *purchasesManager, NSError *error) {
@@ -155,7 +174,7 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath
155174
}];
156175
}
157176
} else if ([cell isEqual:self.enableVideoOnlyFeature]) {
158-
if ([manager didUserBuyEnableVideoOnlyFeature])
177+
if ([manager hasVideoRecordingFeature])
159178
return;
160179
if ([[[cell textLabel] text] isEqualToString:NSLocalizedString(@"Tap to refresh from AppStore.", nil)]) {
161180
[manager reloadProductsWithHandler:^(InAppPurchasesManager *purchasesManager, NSError *error) {
@@ -204,11 +223,11 @@ - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)ce
204223
InAppPurchasesManager *manager = [InAppPurchasesManager sharedManager];
205224
NSArray *products = [manager products];
206225
if ([products count] > 0) {
207-
[self fillRestoreRemoveAdsAndEnableVideoRow];
226+
[self fillRestoreProModeAquiredRow];
208227
} else {
209228
[manager reloadProductsWithHandler:^(InAppPurchasesManager *purchasesManager, NSError *error) {
210229
if (!error) {
211-
[self fillRestoreRemoveAdsAndEnableVideoRow];
230+
[self fillRestoreProModeAquiredRow];
212231
}
213232
}];
214233
}
@@ -251,7 +270,7 @@ - (void)fillRestoreiAdsRow {
251270
InAppPurchasesManager *manager = [InAppPurchasesManager sharedManager];
252271
NSArray *products = [manager products];
253272

254-
if ([manager didUserBuyProBundle] || [manager didUserBuyRemoveiAdsFeature]) {
273+
if ([manager hasAdRemovalFeature]) {
255274
self.disableiAds.textLabel.text = kiAdsFeatureInstalled;
256275
self.disableiAds.detailTextLabel.text = @"";
257276
[self.disableiAds setNeedsDisplay];
@@ -265,16 +284,16 @@ - (void)fillRestoreiAdsRow {
265284
});
266285
}
267286

268-
- (void)fillRestoreRemoveAdsAndEnableVideoRow {
287+
- (void)fillRestoreProModeAquiredRow {
269288
dispatch_async(dispatch_get_main_queue(), ^{
270289
InAppPurchasesManager *manager = [InAppPurchasesManager sharedManager];
271290
NSArray *products = [manager products];
272291
UITableViewCell * disableAdsAndEnableVideo = self.disableAdsAndEnableVideoRecording;
273-
if ([manager didUserBuyRemoveiAdsFeatureAndEnableVideo]) {
292+
if ([manager hasProMode]) {
274293
disableAdsAndEnableVideo.textLabel.text = kiAdsRemovedANdVideoEnabledInstalled;
275294
disableAdsAndEnableVideo.detailTextLabel.text = @"";
276295
} else if ([products count] > 0) {
277-
SKProduct *disableAdsAndEnableVideoProduct = [manager productWithIdentifier:RemoveAdsAndEnableVideoIdentifier];
296+
SKProduct *disableAdsAndEnableVideoProduct = [manager productWithIdentifier:ProModeAquiredIdentifier];
278297
if (disableAdsAndEnableVideoProduct == nil) {
279298
return;
280299
}
@@ -293,8 +312,8 @@ - (void)fillRestoreEnableTorchFeatureRow {
293312
UITableViewCell * enableTorchFeature = self.enableTorchFeature;
294313

295314

296-
if ([manager didUserBuyProBundle] || [manager didUserBuyEnableTorchFeature]) {
297-
enableTorchFeature.textLabel.text = NSLocalizedString(@"Torch Feature Enabled", nil);
315+
if ([manager hasTorchFeature]) {
316+
enableTorchFeature.textLabel.text = kTorchFeatureInstalled;
298317
enableTorchFeature.detailTextLabel.text = @"";
299318
} else if ([products count] > 0) {
300319
SKProduct *enableTorchFeatureProduct = [manager productWithIdentifier:EnableTorchFeatureIdentifier];
@@ -315,8 +334,8 @@ - (void)fillRestoreEnableVideoOnlyFeatureRow {
315334
NSArray *products = [manager products];
316335
UITableViewCell * enableVideoOnlyFeature = self.enableVideoOnlyFeature;
317336

318-
if ([manager didUserBuyProBundle] || [manager didUserBuyEnableVideoOnlyFeature]) {
319-
enableVideoOnlyFeature.textLabel.text = @"Video Feature Enabled";
337+
if ([manager hasVideoRecordingFeature]) {
338+
enableVideoOnlyFeature.textLabel.text = kVideoFeatureEnabled;
320339
enableVideoOnlyFeature.detailTextLabel.text = @"";
321340
} else if ([products count] > 0) {
322341
SKProduct *enableVideoOnlyFeatureProduct = [manager productWithIdentifier:EnableVideoOnlyFeatureIdentifier];
@@ -370,7 +389,7 @@ - (void)restoreThePurchases {
370389
[[InAppPurchasesManager sharedManager] restorePurchasesWithHandler:^(InAppPurchasesManager *purchasesManager, NSError *error) {
371390
if (!error) {
372391
[self fillRestoreiAdsRow];
373-
[self fillRestoreRemoveAdsAndEnableVideoRow];
392+
[self fillRestoreProModeAquiredRow];
374393
[self fillRestoreEnableTorchFeatureRow];
375394
[self fillRestoreEnableVideoOnlyFeatureRow];
376395
}

RemoteCam/Constants.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ NS_ASSUME_NONNULL_BEGIN
1212

1313
@interface Constants : NSObject
1414
+ (NSString *)RemoveAds;
15-
+ (NSString *)RemoveAdsAndEnableVideo;
15+
+ (NSString *)ProModeAquired;
1616
+ (NSString *)EnableTorch;
1717
+ (NSString *)EnableVideoOnly;
1818
@end

RemoteCam/Constants.m

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ + (NSString *)RemoveAds {
1414
return @"RemoveAds";
1515
}
1616

17-
+(NSString *)RemoveAdsAndEnableVideo {
18-
return @"RemoveAdsAndEnableVideo";
17+
+(NSString *)ProModeAquired {
18+
return @"ProModeAquired";
1919
}
2020

2121
+(NSString *)EnableTorch {

RemoteCam/InAppPurchasesManager.h

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,17 +36,30 @@ typedef void(^InAppPurchasesManagerHandler)(InAppPurchasesManager *purchasesMana
3636

3737
- (SKProduct *)productWithIdentifier:(NSString *)identifier;
3838

39+
#pragma mark - Centralized Feature Availability (Recommended API)
40+
// These methods check both Pro bundle and individual purchases
41+
// Use these instead of checking individual purchase methods directly
42+
43+
- (BOOL)hasAdRemovalFeature;
44+
- (BOOL)hasVideoRecordingFeature;
45+
- (BOOL)hasTorchFeature;
46+
- (BOOL)hasProMode;
47+
48+
#pragma mark - Individual Purchase Status (Internal Use)
49+
// These methods check specific purchases only
50+
// Use centralized feature methods above instead
51+
3952
- (BOOL)didUserBuyRemoveiAdsFeature;
4053

41-
- (BOOL)didUserBuyRemoveiAdsFeatureAndEnableVideo;
54+
- (BOOL)didUserBuyProMode;
4255

4356
- (BOOL)didUserBuyEnableTorchFeature;
4457

4558
- (BOOL)didUserBuyEnableVideoOnlyFeature;
4659

4760
- (BOOL)didUserBuyProBundle;
4861

49-
- (void)setDidUserBuyRemoveiAdsAndEnableVideoFeatures:(BOOL)feature;
62+
- (void)setDidUserBuyProMode:(BOOL)feature;
5063

5164
- (void)setDidUserBuyEnableTorchFeature:(BOOL)feature;
5265

RemoteCam/InAppPurchasesManager.m

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -84,11 +84,11 @@ - (void)setDidUserBuyRemoveiAdsFeatures:(BOOL)feature {
8484
[defaults synchronize];
8585
}
8686

87-
- (BOOL)didUserBuyRemoveiAdsFeatureAndEnableVideo {
87+
- (BOOL)didUserBuyProMode {
8888
BOOL didBuyiAds = FALSE;
8989
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
90-
if ([defaults objectForKey:didBuyRemoveAdsAndEnableVideo]) {
91-
didBuyiAds = [defaults boolForKey:didBuyRemoveAdsAndEnableVideo];
90+
if ([defaults objectForKey:didBuyProMode]) {
91+
didBuyiAds = [defaults boolForKey:didBuyProMode];
9292
}
9393
return didBuyiAds;
9494
};
@@ -112,21 +112,34 @@ - (BOOL)didUserBuyEnableVideoOnlyFeature {
112112
};
113113

114114
- (BOOL)didUserBuyProBundle {
115-
return [self didUserBuyRemoveiAdsFeatureAndEnableVideo];
115+
return [self didUserBuyProMode];
116116
};
117117

118-
- (void)setDidUserBuyRemoveiAdsAndEnableVideoFeatures:(BOOL)feature {
118+
#pragma mark - Centralized Feature Availability
119+
120+
- (BOOL)hasAdRemovalFeature {
121+
return [self didUserBuyProBundle] || [self didUserBuyRemoveiAdsFeature];
122+
}
123+
124+
- (BOOL)hasVideoRecordingFeature {
125+
return [self didUserBuyProBundle] || [self didUserBuyEnableVideoOnlyFeature];
126+
}
127+
128+
- (BOOL)hasTorchFeature {
129+
return [self didUserBuyProBundle] || [self didUserBuyEnableTorchFeature];
130+
}
131+
132+
- (BOOL)hasProMode {
133+
return [self didUserBuyProBundle];
134+
}
135+
136+
- (void)setDidUserBuyProMode:(BOOL)feature {
119137
if (feature) {
120-
// Pro bundle unlocks all features
121-
[self setDidUserBuyRemoveiAdsFeatures:TRUE];
122-
[self setDidUserBuyEnableTorchFeature:TRUE];
123-
[self setDidUserBuyEnableVideoOnlyFeature:TRUE];
124-
125-
[[NSNotificationCenter defaultCenter] postNotificationName:Constants.RemoveAdsAndEnableVideo
138+
[[NSNotificationCenter defaultCenter] postNotificationName:Constants.ProModeAquired
126139
object:nil];
127140
}
128141
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
129-
[defaults setBool:feature forKey:didBuyRemoveAdsAndEnableVideo];
142+
[defaults setBool:feature forKey:didBuyProMode];
130143
[defaults synchronize];
131144
}
132145

@@ -152,7 +165,7 @@ - (void)reloadProductsWithHandler:(InAppPurchasesManagerHandler)handler {
152165
req = nil;
153166
}
154167
self.productRefreshHandler = handler;
155-
NSSet *_products = [NSSet setWithObjects:RemoveiAdsFeatureIdentifier, RemoveAdsAndEnableVideoIdentifier, EnableTorchFeatureIdentifier, EnableVideoOnlyFeatureIdentifier, nil];
168+
NSSet *_products = [NSSet setWithObjects:RemoveiAdsFeatureIdentifier, ProModeAquiredIdentifier, EnableTorchFeatureIdentifier, EnableVideoOnlyFeatureIdentifier, nil];
156169
req = [[SKProductsRequest alloc] initWithProductIdentifiers:_products];
157170
[req setDelegate:self];
158171
[req start];
@@ -204,8 +217,8 @@ - (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)tran
204217
if (self.buyProductHandler)
205218
self.buyProductHandler(self, nil);
206219
}
207-
if ([[[transaction payment] productIdentifier] isEqualToString:RemoveAdsAndEnableVideoIdentifier]) {
208-
[self setDidUserBuyRemoveiAdsAndEnableVideoFeatures:TRUE];
220+
if ([[[transaction payment] productIdentifier] isEqualToString:ProModeAquiredIdentifier]) {
221+
[self setDidUserBuyProMode:TRUE];
209222
if (self.buyProductHandler)
210223
self.buyProductHandler(self, nil);
211224
}
@@ -227,7 +240,7 @@ - (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)tran
227240
if (self.buyProductHandler)
228241
self.buyProductHandler(self, transaction.error);
229242
}
230-
if ([[[transaction payment] productIdentifier] isEqualToString:RemoveAdsAndEnableVideoIdentifier]) {
243+
if ([[[transaction payment] productIdentifier] isEqualToString:ProModeAquiredIdentifier]) {
231244
if (self.buyProductHandler)
232245
self.buyProductHandler(self, transaction.error);
233246
}

RemoteCam/MonitorPhotoStates.swift

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,8 @@ extension RemoteCamSession {
2626
}) { (success: Bool, _: Error?) in
2727
if success {
2828
print("Saved photo on monitor!")
29-
// Increment media capture counter for review prompt (monitor side only)
30-
var count = UserDefaults.standard.integer(forKey: mediaCaptureCounterKey)
31-
count += 1
32-
UserDefaults.standard.set(count, forKey: mediaCaptureCounterKey)
33-
34-
// Show review prompt after 10 captures
35-
if count >= 10 {
36-
DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
37-
showReviewPromptIfAppropriate()
38-
}
29+
DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
30+
showReviewPromptIfAppropriate()
3931
}
4032
} else {
4133
print("Failed to save photo on monitor!")

RemoteCam/MonitorVideoStates.swift

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -219,16 +219,8 @@ extension MonitorVideoStates {
219219
if !success {
220220
showError(NSLocalizedString("Unable to save video to Photos app", comment: ""))
221221
} else {
222-
// Increment media capture counter for review prompt
223-
var count = UserDefaults.standard.integer(forKey: mediaCaptureCounterKey)
224-
count += 1
225-
UserDefaults.standard.set(count, forKey: mediaCaptureCounterKey)
226-
227-
// Show review prompt after 10 captures
228-
if count >= 10 {
229-
DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
230-
showReviewPromptIfAppropriate()
231-
}
222+
DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
223+
showReviewPromptIfAppropriate()
232224
}
233225
}
234226

RemoteCam/MonitorViewController.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -456,7 +456,7 @@ public class MonitorViewController: iAdViewController, UIImagePickerControllerDe
456456
}
457457

458458
@IBAction func toggleTorch(sender: UIButton) {
459-
if InAppPurchasesManager.shared().didUserBuyEnableTorchFeature() {
459+
if InAppPurchasesManager.shared().hasTorchFeature() {
460460
session ! UICmd.ToggleTorch()
461461
} else {
462462
showSettings(sender: settingsButton)
@@ -664,7 +664,7 @@ public class MonitorViewController: iAdViewController, UIImagePickerControllerDe
664664

665665

666666
@objc private func onProgrammaticTorchButtonTapped() {
667-
if InAppPurchasesManager.shared().didUserBuyEnableTorchFeature() {
667+
if InAppPurchasesManager.shared().hasTorchFeature() {
668668
session ! UICmd.ToggleTorch()
669669
} else {
670670
showSettings(sender: settingsButton)
@@ -843,7 +843,7 @@ public class MonitorViewController: iAdViewController, UIImagePickerControllerDe
843843
}
844844

845845
@objc func onSegmentedControlChanged(event: UIEvent) {
846-
if InAppPurchasesManager.shared().didUserBuyRemoveiAdsFeatureAndEnableVideo() || InAppPurchasesManager.shared().didUserBuyEnableVideoOnlyFeature() {
846+
if InAppPurchasesManager.shared().hasVideoRecordingFeature() {
847847
var mode = RecordingMode.Photo
848848
switch segmentedControl.selectedSegmentIndex {
849849
case 0:

0 commit comments

Comments
 (0)