2017-11-09 18:43:37 -08:00
//
// PremiumViewController . m
// NewsBlur
//
// Created by Samuel Clay on 11 / 9 / 17.
// Copyright © 2017 NewsBlur . All rights reserved .
//
# import "PremiumViewController.h"
2017-11-10 17:57:50 -08:00
# import "NewsBlur-Swift.h"
2018-10-04 16:59:07 -07:00
# import "PremiumManager.h"
2017-11-09 18:43:37 -08:00
2022-06-22 21:35:54 -06:00
# define kPremiumSubscriptionSection 0
# define kPremiumArchiveSubscriptionSection 1
2022-07-05 20:00:20 -07:00
# define kManageSubscriptionHeight 100
2017-11-09 18:43:37 -08:00
@ interface PremiumViewController ( )
@ end
@ implementation PremiumViewController
- ( void ) viewDidLoad {
[ super viewDidLoad ] ;
2020-08-29 21:19:32 -07:00
self . appDelegate = [ NewsBlurAppDelegate sharedAppDelegate ] ;
2017-11-09 18:43:37 -08:00
2017-11-10 17:37:31 -08:00
UIBarButtonItem * cancelButton = [ [ UIBarButtonItem alloc ] initWithTitle : @ "Done"
style : UIBarButtonItemStylePlain
target : self
action : @ selector ( closeDialog : ) ] ;
[ self . navigationItem setLeftBarButtonItem : cancelButton ] ;
2017-11-09 18:43:37 -08:00
}
- ( void ) viewWillAppear : ( BOOL ) animated {
[ super viewWillAppear : animated ] ;
2017-11-16 16:47:01 -08:00
UIBarButtonItem * restoreButton = [ [ UIBarButtonItem alloc ] initWithTitle : @ "Restore"
style : UIBarButtonItemStylePlain
target : self
action : @ selector ( restorePurchase : ) ] ;
[ self . navigationItem setRightBarButtonItem : restoreButton ] ;
2022-06-22 21:35:54 -06:00
2017-11-28 16:22:46 -08:00
self . navigationItem . title = @ "NewsBlur Premium" ;
2017-11-09 18:43:37 -08:00
[ self loadProducts ] ;
2022-06-22 21:35:54 -06:00
self . premiumTable . tableFooterView = [ self makePolicyView ] ;
2017-11-15 10:47:57 -08:00
[ self updateTheme ] ;
2017-11-09 18:43:37 -08:00
}
- ( void ) closeDialog : ( id ) sender {
[ self dismissViewControllerAnimated : YES completion : nil ] ;
}
2022-06-22 21:35:54 -06:00
- ( NSInteger ) rowsInSection : ( NSInteger ) section {
switch ( section ) {
case kPremiumSubscriptionSection :
return self . appDelegate . premiumManager . premiumReasons . count + 2 ;
break ;
case kPremiumArchiveSubscriptionSection :
return self . appDelegate . premiumManager . premiumArchiveReasons . count + 1 ;
break ;
}
return 0 ;
}
- ( UIView * ) makeManageSubscriptionView {
2022-07-05 20:00:20 -07:00
CGSize viewSize = CGSizeMake ( self . view . frame . size . width , kManageSubscriptionHeight ) ;
2022-06-22 21:35:54 -06:00
UIView * view = [ [ UIView alloc ] initWithFrame : CGRectMake ( 0 , 0 , viewSize . width , viewSize . height ) ] ;
UIView * button = [ self makeButtonWithTitle : @ "Manage Subscription" forURL : @ "https://apps.apple.com/account/subscriptions" ] ;
button . frame = CGRectMake ( ( ( viewSize . width - CGRectGetWidth ( button . frame ) ) / 2 ) - 20 , 15 , CGRectGetWidth ( button . frame ) + 40 , CGRectGetHeight ( button . frame ) + 5 ) ;
[ view addSubview : button ] ;
UILabel * label = [ UILabel new ] ;
if ( self . appDelegate . premiumExpire ! = 0 ) {
NSDate * date = [ NSDate dateWithTimeIntervalSince1970 : self . appDelegate . premiumExpire ] ;
NSDateFormatter * dateFormatter = [ [ NSDateFormatter alloc ] init ] ;
[ dateFormatter setDateFormat : @ "MMMM d, yyyy" ] ;
label . text = [ NSString stringWithFormat : @ "Your premium subscription will renew on %@" , [ dateFormatter stringFromDate : date ] ] ;
} else {
label . text = @ "Your premium subscription is set to never expire. Whoa!" ;
}
label . textAlignment = NSTextAlignmentCenter ;
label . numberOfLines = 0 ;
2022-07-06 21:07:15 -07:00
label . font = [ UIFont fontWithName : @ "WhitneySSm-Medium" size : [ UIFont smallSystemFontSize ] ] ;
2022-06-22 21:35:54 -06:00
label . textColor = UIColorFromRGB ( 0 x0c0c0c ) ;
CGSize measuredSize = [ label . text sizeWithAttributes : @ { NSFontAttributeName : label . font } ] ;
2022-07-05 20:00:20 -07:00
label . frame = CGRectMake ( ( viewSize . width - measuredSize . width ) / 2 , 15 + CGRectGetHeight ( button . frame ) + 15 , measuredSize . width , measuredSize . height ) ;
2022-06-22 21:35:54 -06:00
[ view addSubview : label ] ;
return view ;
}
- ( UIView * ) makePolicyView {
2022-07-05 20:00:20 -07:00
CGSize viewSize = CGSizeMake ( self . view . frame . size . width , 120 ) ;
2022-06-22 21:35:54 -06:00
UIView * view = [ [ UIView alloc ] initWithFrame : CGRectMake ( 0 , 0 , viewSize . width , viewSize . height ) ] ;
UIView * button = [ self makeButtonWithTitle : @ "Privacy Policy" forURL : @ "https://newsblur.com/privacy/" ] ;
2022-07-05 20:00:20 -07:00
CGFloat buttonHeight = CGRectGetHeight ( button . frame ) + 5 ;
2022-06-22 21:35:54 -06:00
2022-07-05 20:00:20 -07:00
button . frame = CGRectMake ( ( ( viewSize . width - CGRectGetWidth ( button . frame ) ) / 2 ) - 20 , 15 , CGRectGetWidth ( button . frame ) + 40 , buttonHeight ) ;
2022-06-22 21:35:54 -06:00
[ view addSubview : button ] ;
button = [ self makeButtonWithTitle : @ "Terms of Use" forURL : @ "https://newsblur.com/tos/" ] ;
2022-07-05 20:00:20 -07:00
button . frame = CGRectMake ( ( ( viewSize . width - CGRectGetWidth ( button . frame ) ) / 2 ) - 20 , 15 + buttonHeight + 15 , CGRectGetWidth ( button . frame ) + 40 , buttonHeight ) ;
2022-06-22 21:35:54 -06:00
[ view addSubview : button ] ;
return view ;
}
- ( UIView * ) makeButtonWithTitle : ( NSString * ) title forURL : ( NSString * ) urlString {
UIAction * action = [ UIAction actionWithHandler : ^ ( __kindof UIAction * _Nonnull action ) {
NSURL * url = [ NSURL URLWithString : urlString ] ;
[ UIApplication . sharedApplication openURL : url options : @ { } completionHandler : nil ] ;
} ] ;
action . title = title ;
UIButton * button = [ UIButton buttonWithType : UIButtonTypeSystem primaryAction : action ] ;
button . tintColor = UIColor . whiteColor ;
button . backgroundColor = UIColorFromFixedRGB ( 0 x939EAF ) ;
button . layer . cornerRadius = 10 ;
[ button sizeToFit ] ;
return button ;
2018-10-22 13:05:28 -07:00
}
2017-11-15 10:47:57 -08:00
- ( void ) updateTheme {
[ super updateTheme ] ;
2022-06-22 21:35:54 -06:00
self . premiumTable . backgroundColor = UIColorFromRGB ( 0 xf4f4f4 ) ;
2017-11-15 10:47:57 -08:00
self . view . backgroundColor = UIColorFromRGB ( 0 xf4f4f4 ) ;
2022-06-22 21:35:54 -06:00
[ self . premiumTable reloadData ] ;
2017-11-14 21:46:21 -08:00
}
2017-11-09 18:43:37 -08:00
# pragma mark - StoreKit
- ( void ) loadProducts {
2022-06-22 21:35:54 -06:00
[ self . appDelegate . premiumManager loadProducts ] ;
2017-11-09 18:43:37 -08:00
}
2018-10-04 16:59:07 -07:00
- ( void ) loadedProducts {
2022-06-22 21:35:54 -06:00
[ self . premiumTable reloadData ] ;
}
- ( SKProduct * ) productForSection : ( NSInteger ) section {
if ( section = = kPremiumSubscriptionSection ) {
return self . appDelegate . premiumManager . premiumProduct ;
} else {
return self . appDelegate . premiumManager . premiumArchiveProduct ;
}
2017-11-09 18:43:37 -08:00
}
- ( void ) purchase : ( SKProduct * ) product {
2022-06-22 21:35:54 -06:00
[ self . appDelegate . premiumManager purchase : product ] ;
2017-11-09 18:43:37 -08:00
}
- ( IBAction ) restorePurchase : ( id ) sender {
2022-06-22 21:35:54 -06:00
[ self . appDelegate . premiumManager restorePurchase ] ;
2017-11-09 18:43:37 -08:00
}
2018-10-04 16:59:07 -07:00
- ( void ) finishedTransaction {
2022-06-22 21:35:54 -06:00
[ self . premiumTable reloadData ] ;
2017-11-09 18:43:37 -08:00
}
2018-10-04 16:59:07 -07:00
- ( void ) informError : ( id ) error {
[ super informError : error ] ;
2017-11-10 17:37:31 -08:00
}
2018-08-17 14:11:59 -04:00
2017-11-09 18:43:37 -08:00
# pragma mark - Table Delegate
- ( NSInteger ) numberOfSectionsInTableView : ( UITableView * ) tableView {
2022-06-22 21:35:54 -06:00
return 2 ;
2017-11-09 18:43:37 -08:00
}
- ( NSInteger ) tableView : ( UITableView * ) tableView numberOfRowsInSection : ( NSInteger ) section {
2022-06-22 21:35:54 -06:00
return [ self rowsInSection : section ] ;
2017-11-09 18:43:37 -08:00
}
- ( UITableViewCell * ) tableView : ( UITableView * ) tableView cellForRowAtIndexPath : ( NSIndexPath * ) indexPath {
2017-11-14 21:46:21 -08:00
UITableViewCell * cell ;
2022-06-22 21:35:54 -06:00
NSInteger rowsInSection = [ self rowsInSection : indexPath . section ] ;
2017-11-09 18:43:37 -08:00
2022-06-22 21:35:54 -06:00
if ( indexPath . section = = kPremiumSubscriptionSection && indexPath . row = = rowsInSection - 2 ) {
static NSString * DogCellIdentifier = @ "PremiumDogCell" ;
cell = [ tableView dequeueReusableCellWithIdentifier : DogCellIdentifier ] ;
if ( ! cell ) {
cell = [ [ UITableViewCell alloc ] initWithStyle : UITableViewCellStyleDefault reuseIdentifier : DogCellIdentifier ] ;
}
cell . backgroundColor = UIColorFromRGB ( 0 xf4f4f4 ) ;
cell . selectionStyle = UITableViewCellSelectionStyleNone ;
UIImageView * imgView = [ [ UIImageView alloc ] init ] ;
imgView . translatesAutoresizingMaskIntoConstraints = NO ;
imgView . tag = 1 ;
imgView . contentMode = UIViewContentModeScaleAspectFit ;
[ cell addSubview : imgView ] ;
[ cell addConstraint : [ NSLayoutConstraint constraintWithItem : imgView attribute : NSLayoutAttributeCenterX relatedBy : NSLayoutRelationEqual toItem : cell attribute : NSLayoutAttributeCenterX multiplier : 1.0 constant : 0 ] ] ;
[ cell addConstraint : [ NSLayoutConstraint constraintWithItem : imgView attribute : NSLayoutAttributeTop relatedBy : NSLayoutRelationEqual toItem : cell attribute : NSLayoutAttributeTop multiplier : 1.0 constant : 12 ] ] ;
[ imgView addConstraint : [ NSLayoutConstraint constraintWithItem : imgView attribute : NSLayoutAttributeHeight relatedBy : NSLayoutRelationEqual toItem : nil attribute : NSLayoutAttributeNotAnAttribute multiplier : 1.0 constant : 96 ] ] ;
UIImageView * _imgView = ( UIImageView * ) [ cell viewWithTag : 1 ] ;
_imgView . image = [ UIImage imageNamed : @ "Lyric.jpg" ] ;
} else if ( indexPath . row < rowsInSection - 1 ) {
static NSString * ReasonsCellIdentifier = @ "PremiumReasonsCell" ;
cell = [ tableView dequeueReusableCellWithIdentifier : ReasonsCellIdentifier ] ;
2017-11-14 21:46:21 -08:00
if ( ! cell ) {
2022-06-22 21:35:54 -06:00
cell = [ [ UITableViewCell alloc ] initWithStyle : UITableViewCellStyleDefault reuseIdentifier : ReasonsCellIdentifier ] ;
2017-11-14 21:46:21 -08:00
}
2017-11-15 10:47:57 -08:00
2022-06-22 21:35:54 -06:00
BOOL isArchive = indexPath . section = = kPremiumArchiveSubscriptionSection ;
NSArray * reasons = isArchive ? self . appDelegate . premiumManager . premiumArchiveReasons : self . appDelegate . premiumManager . premiumReasons ;
2017-11-15 10:47:57 -08:00
cell . backgroundColor = UIColorFromRGB ( 0 xf4f4f4 ) ;
2017-11-09 18:43:37 -08:00
cell . selectionStyle = UITableViewCellSelectionStyleNone ;
2022-06-22 21:35:54 -06:00
cell . textLabel . text = reasons [ indexPath . row ] [ 0 ] ;
2022-07-06 21:07:15 -07:00
cell . textLabel . font = [ UIFont fontWithName : @ "WhitneySSm-Medium" size : 14.0 ] ;
2017-11-15 10:47:57 -08:00
cell . textLabel . textColor = UIColorFromRGB ( 0 x0c0c0c ) ;
2017-11-10 17:37:31 -08:00
cell . textLabel . numberOfLines = 2 ;
2017-11-14 21:46:21 -08:00
CGSize itemSize = CGSizeMake ( 18 , 18 ) ;
2022-06-23 20:28:44 -06:00
NSString * imageName = reasons [ indexPath . row ] [ 1 ] ;
UIImage * image = [ UIImage imageNamed : imageName ] ;
if ( ThemeManager . themeManager . isDarkTheme ) {
cell . imageView . image = [ image imageWithTintColor : UIColor . whiteColor ] ;
} else {
cell . imageView . image = image ;
}
2017-11-14 21:46:21 -08:00
cell . imageView . contentMode = UIViewContentModeScaleAspectFill ;
cell . imageView . clipsToBounds = NO ;
2017-11-09 18:43:37 -08:00
UIGraphicsBeginImageContextWithOptions ( itemSize , NO , UIScreen . mainScreen . scale ) ;
CGRect imageRect = CGRectMake ( 0.0 , 0.0 , itemSize . width , itemSize . height ) ;
[ cell . imageView . image drawInRect : imageRect ] ;
cell . imageView . image = UIGraphicsGetImageFromCurrentImageContext ( ) ;
UIGraphicsEndImageContext ( ) ;
2022-06-22 21:35:54 -06:00
} else {
static NSString * CellIdentifier = @ "PremiumCell" ;
cell = [ tableView dequeueReusableCellWithIdentifier : CellIdentifier ] ;
2017-11-14 21:46:21 -08:00
if ( ! cell ) {
2022-06-22 21:35:54 -06:00
cell = [ [ UITableViewCell alloc ] initWithStyle : UITableViewCellStyleSubtitle reuseIdentifier : CellIdentifier ] ;
2017-11-14 21:46:21 -08:00
}
2022-06-22 21:35:54 -06:00
BOOL isSubscribed = NO ;
SKProduct * product = [ self productForSection : indexPath . section ] ;
2017-11-09 18:43:37 -08:00
cell . selectionStyle = UITableViewCellSelectionStyleBlue ;
2017-11-15 10:47:57 -08:00
cell . backgroundColor = UIColorFromRGB ( 0 xf4f4f4 ) ;
2022-07-06 21:07:15 -07:00
cell . textLabel . font = [ UIFont fontWithName : @ "WhitneySSm-Medium" size : 18.0 ] ;
2017-11-15 10:47:57 -08:00
cell . textLabel . textColor = UIColorFromRGB ( 0 x203070 ) ;
2017-11-15 11:05:24 -08:00
cell . textLabel . numberOfLines = 2 ;
2022-07-06 21:07:15 -07:00
cell . detailTextLabel . font = [ UIFont fontWithName : @ "WhitneySSm-Medium" size : 18.0 ] ;
2017-11-15 10:47:57 -08:00
cell . detailTextLabel . textColor = UIColorFromRGB ( 0 x0c0c0c ) ;
2017-11-14 21:46:21 -08:00
NSNumberFormatter * formatter = [ [ NSNumberFormatter alloc ] init ] ;
[ formatter setFormatterBehavior : NSNumberFormatterBehavior10_4 ] ;
[ formatter setNumberStyle : NSNumberFormatterCurrencyStyle ] ;
[ formatter setLocale : product . priceLocale ] ;
2022-06-22 21:35:54 -06:00
if ( indexPath . section = = kPremiumSubscriptionSection && self . appDelegate . isPremium ) {
if ( self . appDelegate . isPremiumArchive ) {
cell . textLabel . text = @ "Your premium archive subscription includes everything above" ;
} else {
cell . textLabel . text = @ "Your premium subscription is active" ;
}
cell . selectionStyle = UITableViewCellSelectionStyleNone ;
isSubscribed = YES ;
} else if ( indexPath . section = = kPremiumArchiveSubscriptionSection && self . appDelegate . isPremiumArchive ) {
cell . textLabel . text = @ "Your premium archive subscription is active" ;
cell . selectionStyle = UITableViewCellSelectionStyleNone ;
isSubscribed = YES ;
} else if ( product = = nil ) {
cell . textLabel . text = @ "Not currently available" ;
} else if ( ! product . localizedTitle ) {
cell . textLabel . text = @ "NewsBlur Premium Subscription" ;
} else {
cell . textLabel . text = product . localizedTitle ;
}
if ( ! isSubscribed && product ! = nil ) {
cell . detailTextLabel . text = [ NSString stringWithFormat : @ "%@ per year (%@/month)" , [ formatter stringFromNumber : product . price ] , [ formatter stringFromNumber : @ ( round ( [ product . price doubleValue ] / 12. f ) ) ] ] ;
2017-11-30 15:24:26 -08:00
} else {
2022-06-22 21:35:54 -06:00
cell . detailTextLabel . text = nil ;
2017-11-30 15:24:26 -08:00
}
2017-11-14 21:46:21 -08:00
UILabel * label = [ [ UILabel alloc ] init ] ;
2022-06-22 21:35:54 -06:00
label . text = isSubscribed ? @ "✅" : @ "👉🏽" ;
2017-11-14 21:46:21 -08:00
label . opaque = NO ;
label . backgroundColor = UIColor . clearColor ;
2022-07-06 21:07:15 -07:00
label . font = [ UIFont fontWithName : @ "WhitneySSm-Medium" size : 18.0 ] ;
2017-11-14 21:46:21 -08:00
CGSize measuredSize = [ label . text sizeWithAttributes : @ { NSFontAttributeName : label . font } ] ;
label . frame = CGRectMake ( 0 , 0 , measuredSize . width , measuredSize . height ) ;
UIGraphicsBeginImageContextWithOptions ( label . bounds . size , label . opaque , 0.0 ) ;
[ label . layer renderInContext : UIGraphicsGetCurrentContext ( ) ] ;
cell . imageView . image = UIGraphicsGetImageFromCurrentImageContext ( ) ;
}
return cell ;
}
2022-06-22 21:35:54 -06:00
- ( CGFloat ) tableView : ( UITableView * ) tableView heightForRowAtIndexPath : ( NSIndexPath * ) indexPath {
NSInteger rowsInSection = [ self rowsInSection : indexPath . section ] ;
if ( indexPath . section = = kPremiumSubscriptionSection && indexPath . row = = rowsInSection - 2 ) {
return 120 ;
} else if ( indexPath . row < [ self tableView : tableView numberOfRowsInSection : indexPath . section ] - 1 ) {
return 40 ;
} else {
return 60 ;
}
2017-11-14 21:57:41 -08:00
}
2017-11-14 21:46:21 -08:00
2022-06-22 21:35:54 -06:00
- ( UIView * ) tableView : ( UITableView * ) tableView viewForHeaderInSection : ( NSInteger ) section {
UILabel * label = [ [ UILabel alloc ] init ] ;
label . text = section = = kPremiumArchiveSubscriptionSection ? @ " Premium Archive Subscription" : @ " Premium Subscription" ;
label . opaque = YES ;
2022-06-23 20:28:44 -06:00
label . backgroundColor = UIColor . darkGrayColor ;
label . textColor = UIColor . whiteColor ;
2022-07-06 21:07:15 -07:00
label . font = [ UIFont fontWithName : @ "WhitneySSm-Medium" size : 20.0 ] ;
2022-06-22 21:35:54 -06:00
CGSize measuredSize = [ label . text sizeWithAttributes : @ { NSFontAttributeName : label . font } ] ;
label . frame = CGRectMake ( 0 , 0 , measuredSize . width , measuredSize . height ) ;
2017-11-09 18:43:37 -08:00
2022-06-22 21:35:54 -06:00
return label ;
}
2017-11-14 21:57:41 -08:00
2022-06-23 20:28:44 -06:00
- ( CGFloat ) tableView : ( UITableView * ) tableView heightForHeaderInSection : ( NSInteger ) section {
return 60 ;
}
2022-07-05 20:00:20 -07:00
- ( UIView * ) tableView : ( UITableView * ) tableView viewForFooterInSection : ( NSInteger ) section {
if ( section = = kPremiumArchiveSubscriptionSection && self . appDelegate . isPremiumArchive ) {
return [ self makeManageSubscriptionView ] ;
} else if ( section = = kPremiumSubscriptionSection && self . appDelegate . isPremium ) {
return [ self makeManageSubscriptionView ] ;
} else {
return nil ;
}
}
2022-06-22 21:35:54 -06:00
- ( CGFloat ) tableView : ( UITableView * ) tableView heightForFooterInSection : ( NSInteger ) section {
2022-07-05 20:00:20 -07:00
if ( section = = kPremiumArchiveSubscriptionSection && self . appDelegate . isPremiumArchive ) {
return kManageSubscriptionHeight ;
} else if ( section = = kPremiumSubscriptionSection && self . appDelegate . isPremium ) {
return kManageSubscriptionHeight ;
} else {
return 0 ;
}
2017-11-09 18:43:37 -08:00
}
2017-11-10 17:37:31 -08:00
- ( void ) tableView : ( UITableView * ) tableView didSelectRowAtIndexPath : ( NSIndexPath * ) indexPath {
2022-06-22 21:35:54 -06:00
SKProduct * product = [ self productForSection : indexPath . section ] ;
if ( product ! = nil && indexPath . row = = [ self tableView : tableView numberOfRowsInSection : indexPath . section ] - 1 ) {
if ( indexPath . section = = kPremiumSubscriptionSection && ! self . appDelegate . isPremium ) {
[ self purchase : product ] ;
} else if ( indexPath . section = = kPremiumArchiveSubscriptionSection && ! self . appDelegate . isPremiumArchive ) {
[ self purchase : product ] ;
}
2017-11-10 17:37:31 -08:00
}
[ tableView deselectRowAtIndexPath : indexPath animated : YES ] ;
}
2022-06-22 21:35:54 -06:00
2017-11-09 18:43:37 -08:00
@ end