Merge branch 'dev_inapp'

This commit is contained in:
Simon Morlat 2016-08-17 11:38:00 +02:00
commit ec73c08490
13 changed files with 630 additions and 21 deletions

View file

@ -0,0 +1,243 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="10117" systemVersion="15G31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="ShopView">
<connections>
<outlet property="accountBuyButton" destination="0bU-UW-3nR" id="GOQ-1M-4kI"/>
<outlet property="accountProductDescription" destination="Ubj-Hn-QQP" id="itS-zY-QnV"/>
<outlet property="accountProductPrice" destination="Hhk-KZ-LpO" id="rao-hi-s4Y"/>
<outlet property="accountProductTitle" destination="8CD-Y8-Ad3" id="29E-MO-OgE"/>
<outlet property="landscapeView" destination="sVO-4a-t1s" id="9ye-NV-onQ"/>
<outlet property="portraitView" destination="HJH-1o-RXN" id="Hoa-uk-q9s"/>
<outlet property="view" destination="HJH-1o-RXN" id="OKD-FI-yhX"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="eP3-Qs-BZl" userLabel="iphone6MetricsView">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<view tag="1" contentMode="scaleToFill" id="HJH-1o-RXN">
<rect key="frame" x="0.0" y="66" width="375" height="601"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view tag="2" contentMode="scaleToFill" id="Whz-oo-Pwx" userLabel="topBar">
<rect key="frame" x="0.0" y="0.0" width="375" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" tag="3" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="color_F.png" id="h54-RV-eE6" userLabel="backgroundColor">
<rect key="frame" x="0.0" y="0.0" width="375" height="66"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES" flexibleMaxY="YES"/>
</imageView>
<button opaque="NO" tag="4" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="ETk-tB-ZNl" userLabel="dialerBackButton" customClass="UIIconButton">
<rect key="frame" x="299" y="0.0" width="76" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Add contact"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
<state key="normal" image="dialer_back_default.png">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<state key="disabled" image="dialer_back_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onDialerBackClick:" destination="-1" eventType="touchUpInside" id="PJX-d2-pSh"/>
</connections>
</button>
<label opaque="NO" userInteractionEnabled="NO" tag="5" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="SHOP" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="iNt-9d-7si" userLabel="titleLabel">
<rect key="frame" x="0.0" y="0.0" width="375" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="27"/>
<color key="textColor" red="1" green="0.36862745099999999" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</view>
<view clipsSubviews="YES" multipleTouchEnabled="YES" tag="6" contentMode="scaleToFill" id="er6-WR-NP1">
<rect key="frame" x="0.0" y="66" width="375" height="535"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Product description" lineBreakMode="wordWrap" numberOfLines="4" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Ubj-Hn-QQP" userLabel="productDescription">
<rect key="frame" x="16" y="35" width="209" height="50"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="12"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" id="0bU-UW-3nR" userLabel="purchaseButton">
<rect key="frame" x="303" y="31" width="72" height="30"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
<state key="normal" title="Buy"/>
<connections>
<action selector="onPurchaseButtonClick:" destination="-1" eventType="touchUpInside" id="ZX7-nC-4Mi"/>
</connections>
</button>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Product title" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" highlighted="YES" adjustsFontSizeToFit="NO" id="8CD-Y8-Ad3" userLabel="productTitle">
<rect key="frame" x="16" y="11" width="289" height="21"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="center" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="0.5 €" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Hhk-KZ-LpO">
<rect key="frame" x="258" y="35" width="55" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</view>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<simulatedScreenMetrics key="simulatedDestinationMetrics" type="retina47"/>
<point key="canvasLocation" x="235.5" y="318.5"/>
</view>
<view contentMode="scaleToFill" id="FcM-rg-Qrt" userLabel="iphone6MetricsView">
<rect key="frame" x="0.0" y="0.0" width="667" height="375"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<view tag="1" contentMode="scaleToFill" id="sVO-4a-t1s">
<rect key="frame" x="0.0" y="66" width="667" height="309"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view tag="2" contentMode="scaleToFill" id="OGe-ZS-scH" userLabel="topBar">
<rect key="frame" x="0.0" y="0.0" width="667" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" tag="3" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="color_F.png" id="Vi5-Wh-iOm" userLabel="backgroundColor">
<rect key="frame" x="0.0" y="0.0" width="667" height="66"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES" flexibleMaxY="YES"/>
</imageView>
<button opaque="NO" tag="4" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="vX8-wO-ZEN" userLabel="dialerBackButton" customClass="UIIconButton">
<rect key="frame" x="532" y="0.0" width="135" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Add contact"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
<state key="normal" image="dialer_back_default.png">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<state key="disabled" image="dialer_back_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onDialerBackClick:" destination="-1" eventType="touchUpInside" id="vfB-jG-YPr"/>
</connections>
</button>
<label opaque="NO" userInteractionEnabled="NO" tag="5" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="ABOUT" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="wKp-iH-ojJ" userLabel="titleLabel">
<rect key="frame" x="0.0" y="0.0" width="667" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="27"/>
<color key="textColor" red="1" green="0.36862745099999999" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</view>
<view clipsSubviews="YES" multipleTouchEnabled="YES" tag="6" contentMode="scaleToFill" id="Wvv-4f-Oa6">
<rect key="frame" x="0.0" y="66" width="667" height="243"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" tag="7" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="color_C.png" id="UBx-Gi-qTi" userLabel="backgroundColor">
<rect key="frame" x="0.0" y="0.0" width="667" height="178"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES" flexibleMaxY="YES"/>
</imageView>
<imageView userInteractionEnabled="NO" tag="8" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="splashscreen.png" id="UhZ-5i-eU5" userLabel="logoImage">
<rect key="frame" x="8" y="8" width="212" height="161"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" tag="9" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="LINPHONE" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.10000000149011612" id="fss-Tl-kRy" userLabel="nameLabel">
<rect key="frame" x="228" y="16" width="439" height="47"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="41"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" tag="10" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" usesAttributedText="YES" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.10000000149011612" id="ASG-VC-Riv" userLabel="descLabel">
<rect key="frame" x="228" y="71" width="439" height="34"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<attributedString key="attributedText">
<fragment content="The ">
<attributes>
<color key="NSColor" red="1" green="0.36862745099999999" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<font key="NSFont" size="26" name="HelveticaNeue"/>
<paragraphStyle key="NSParagraphStyle" alignment="center" lineBreakMode="truncatingTail" baseWritingDirection="natural" tighteningFactorForTruncation="0.0"/>
</attributes>
</fragment>
<fragment content="libre">
<attributes>
<color key="NSColor" red="1" green="0.36862745099999999" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<font key="NSFont" size="26" name="HelveticaNeue-Italic"/>
<paragraphStyle key="NSParagraphStyle" alignment="center" lineBreakMode="truncatingTail" baseWritingDirection="natural" tighteningFactorForTruncation="0.0"/>
</attributes>
</fragment>
<fragment content=" SIP client">
<attributes>
<color key="NSColor" red="1" green="0.36862745099999999" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<font key="NSFont" size="26" name="HelveticaNeue"/>
<paragraphStyle key="NSParagraphStyle" alignment="center" lineBreakMode="truncatingTail" baseWritingDirection="natural" tighteningFactorForTruncation="0.0"/>
</attributes>
</fragment>
</attributedString>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" tag="11" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Linphone iPhone 3.0" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="oYk-ih-BBi" userLabel="appVersionLabel">
<rect key="frame" x="228" y="115" width="439" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.88235294119999996" green="0.88235294119999996" blue="0.88235294119999996" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" tag="12" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Linphone Core 3.9.0" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="g2W-u5-yxg" userLabel="libVersionLabel">
<rect key="frame" x="228" y="144" width="439" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.88235294119999996" green="0.88235294119999996" blue="0.88235294119999996" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" tag="13" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="https://www.linphone.org" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="uis-xz-Qsa" userLabel="siteURLLabel">
<rect key="frame" x="0.0" y="177" width="333" height="66"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="1" green="0.36862745099999999" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" tag="14" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="7" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" id="ToT-OI-B2F" userLabel="licenseLabel">
<rect key="frame" x="333" y="177" width="334" height="66"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<string key="text">GNU General Public License V2
© 2010-2016 Belledonne Communications</string>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" white="0.33333333333333331" alpha="1" colorSpace="calibratedWhite"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</view>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
<simulatedScreenMetrics key="simulatedDestinationMetrics" type="retina47"/>
<point key="canvasLocation" x="801.5" y="280.5"/>
</view>
<tapGestureRecognizer id="l7c-wq-pii" userLabel="onLinkTap">
<connections>
<action selector="onLinkTap:" destination="-1" id="Ay5-Uz-RDo"/>
</connections>
</tapGestureRecognizer>
</objects>
<resources>
<image name="color_C.png" width="2" height="2"/>
<image name="color_E.png" width="2" height="2"/>
<image name="color_F.png" width="2" height="2"/>
<image name="dialer_back_default.png" width="27" height="27"/>
<image name="dialer_back_disabled.png" width="27" height="27"/>
<image name="splashscreen.png" width="181" height="165"/>
</resources>
</document>

View file

@ -45,6 +45,8 @@ typedef NSString *IAPPurchaseNotificationStatus;
// paid_account_id=test.autorenew_7days
// receipt_validation_url=https://www.linphone.org/inapp.php
// products_list=test.autorenew_7days
// expiry_check_period = 86400
// warn_before_expiry_period = 604800
// Note: in Sandbox mode (test), autorenewal expire time is speed up (see
// http://stackoverflow.com/questions/8815271/what-expiry-date-should-i-see-for-in-app-purchase-in-the-application-sandbox)
// so that 7 days renewal is only 3 minutes and:
@ -57,11 +59,19 @@ typedef NSString *IAPPurchaseNotificationStatus;
@interface InAppProductsManager : NSObject <SKProductsRequestDelegate, SKPaymentTransactionObserver> {
NSString *latestReceiptMD5;
time_t lastCheck;
time_t expiryTime;
}
@property(nonatomic, strong) IAPPurchaseNotificationStatus status;
@property(nonatomic, strong) NSMutableArray *productsAvailable;
@property(nonatomic, strong) NSMutableArray *productsIDPurchased;
//Period of time between each expiration check. Default value is given in linphonerc.
@property time_t checkPeriod;
//Period of time before expiration during which we warn the user about the need to renew the account.
@property time_t warnBeforeExpiryPeriod;
//The notification category to use for displaying notification related to account expiry.
@property NSString *notificationCategory;
// TRUE when in app purchase capability is available - not modified during runtime
@property(readonly) BOOL enabled;
@ -82,7 +92,7 @@ typedef NSString *IAPPurchaseNotificationStatus;
andEmail:(NSString *)email
monthly:(BOOL)monthly;
// Purchase a product. You should not use this if manager is not available yet.
- (BOOL)purchaseWitID:(NSString *)productID;
- (BOOL)purchaseWithID:(NSString *)productID;
// Activate purchased account.
- (BOOL)activateAccount:(NSString *)phoneNumber;
@ -92,6 +102,9 @@ typedef NSString *IAPPurchaseNotificationStatus;
// Warning: on first run, this will open a popup to user to provide iTunes Store credentials
- (BOOL)retrievePurchases;
//Check if account is about to expire, and if yes launch a notification.
- (void)check;
// internal API only due to methods conflict
- (void)XMLRPCRequest:(XMLRPCRequest *)request didReceiveResponse:(XMLRPCResponse *)response;
// internal API only due to methods conflict

View file

@ -18,6 +18,7 @@
*/
#import "InAppProductsManager.h"
#import "ShopView.h"
// In app purchase are not supported by the Simulator
#import <XMLRPCConnection.h>
@ -36,10 +37,16 @@
@property(nonatomic, strong) InAppProductsXMLRPCDelegate *xmlrpc;
@end
@implementation InAppProductsManager
@synthesize checkPeriod;
@synthesize warnBeforeExpiryPeriod;
@synthesize notificationCategory;
// LINPHONE_CAPABILITY_INAPP_PURCHASE must be defined in Linphone Build Settings
#if LINPHONE_CAPABILITY_INAPP_PURCHASE && !TARGET_IPHONE_SIMULATOR
#if 1
- (instancetype)init {
if ((self = [super init]) != nil) {
@ -48,6 +55,14 @@
_initialized = false;
_available = false;
_accountActivationInProgress = false;
checkPeriod = [LinphoneManager.instance lpConfigIntForKey:@"expiry_check_period" inSection:@"in_app_purchase"];
warnBeforeExpiryPeriod = [LinphoneManager.instance lpConfigIntForKey:@"warn_before_expiry_period" inSection:@"in_app_purchase"];
lastCheck = 0;
int testExpiry = [LinphoneManager.instance lpConfigIntForKey:@"expiry_time_test" inSection:@"in_app_purchase"];
if (testExpiry > 0){
expiryTime = time(NULL) + testExpiry;
}else expiryTime = 0;
if (_enabled) {
self.xmlrpc = [[InAppProductsXMLRPCDelegate alloc] init];
_status = kIAPNotReady;
@ -76,7 +91,7 @@
return false;
}
- (BOOL)purchaseWitID:(NSString *)productID {
- (BOOL)purchaseWithID:(NSString *)productID {
if (!_enabled || !_initialized || !_available) {
NSDictionary *dict = @{
@"product_id" : productID,
@ -111,7 +126,7 @@
inSection:@"in_app_purchase"];
self.accountCreationData = @{ @"phoneNumber" : phoneNumber, @"password" : password, @"email" : email };
if (![self purchaseWitID:productID]) {
if (![self purchaseWithID:productID]) {
self.accountCreationData = nil;
}
return true;
@ -301,13 +316,9 @@
NSString *phoneNumber = @"";
LinphoneProxyConfig *config = linphone_core_get_default_proxy_config(LC);
if (config) {
const char *identity = linphone_proxy_config_get_identity(config);
const LinphoneAddress *identity = linphone_proxy_config_get_identity_address(config);
if (identity) {
LinphoneAddress *addr = linphone_core_interpret_url(LC, identity);
if (addr) {
phoneNumber = [NSString stringWithUTF8String:linphone_address_get_username(addr)];
linphone_address_destroy(addr);
}
phoneNumber = [NSString stringWithUTF8String:linphone_address_get_username(identity)];
}
}
return phoneNumber;
@ -476,6 +487,64 @@
NSDictionary *dict = @{ @"error_msg" : errorString };
[self postNotificationforStatus:kIAPReceiptFailed withDict:dict];
}
- (void) presentNotification:(int64_t) remaining{
if (notificationCategory == nil) return;
int days = (int)remaining / (3600 * 24);
NSString * expireText;
if (remaining >= 0){
expireText = [NSString stringWithFormat:NSLocalizedString(@"Your account will expire in %i days.", nil), days];
}else{
expireText = [NSString stringWithFormat:NSLocalizedString(@"Your account has expired.", nil), days];
}
if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground){
UILocalNotification *notification = [[UILocalNotification alloc] init];
if (notification) {
notification.category = notificationCategory;
notification.repeatInterval = 0;
notification.applicationIconBadgeNumber = 1;
notification.alertBody = expireText;
[[UIApplication sharedApplication] presentLocalNotificationNow:notification];
}
}else{
UIAlertController* alert = [UIAlertController alertControllerWithTitle:@"Account expiring"
message:expireText
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* buyAction = [UIAlertAction actionWithTitle:@"Buy" style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
[PhoneMainView.instance changeCurrentView:ShopView.compositeViewDescription];
}];
UIAlertAction* laterAction = [UIAlertAction actionWithTitle:@"Later" style:UIAlertActionStyleCancel
handler:^(UIAlertAction * action) {
// [alert dismissViewControllerAnimated:FALSE];
}];
[alert addAction:buyAction];
[alert addAction:laterAction];
[PhoneMainView.instance presentViewController:alert animated:YES completion:nil];
}
}
- (void) check{
if (!_available) return;
if (expiryTime == 0 || checkPeriod == 0) return;
time_t now = time(NULL);
if (now < lastCheck + checkPeriod) return;
if (now >= expiryTime - warnBeforeExpiryPeriod){
lastCheck = now;
int64_t remaining = (int64_t)expiryTime - (int64_t)now;
[self presentNotification: remaining];
}
}
#else
- (void)postNotificationforStatus:(IAPPurchaseNotificationStatus)status {
_status = status;
@ -497,7 +566,7 @@
[self postNotificationforStatus:kIAPRestoreFailed];
return false;
}
- (BOOL)purchaseWitID:(NSString *)productID {
- (BOOL)purchaseWithID:(NSString *)productID {
[self postNotificationforStatus:kIAPPurchaseFailed];
return FALSE;
}

View file

@ -18,6 +18,7 @@
*/
#import "PhoneMainView.h"
#import "ShopView.h"
#import "linphoneAppDelegate.h"
#import "AddressBook/ABPerson.h"
@ -99,6 +100,7 @@
[self fixRing];
}
}
[LinphoneManager.instance.iapManager check];
}
#pragma deploymate push "ignored-api-availability"
@ -170,6 +172,14 @@
return localRingNotifAction;
}
- (UIUserNotificationCategory *)getAccountExpiryNotificationCategory {
UIMutableUserNotificationCategory *expiryNotification = [[UIMutableUserNotificationCategory alloc] init];
expiryNotification.identifier = @"expiry_notification";
return expiryNotification;
}
- (void)registerForNotifications:(UIApplication *)app {
LinphoneManager *instance = [LinphoneManager instance];
@ -179,7 +189,7 @@
UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert;
NSSet *categories =
[NSSet setWithObjects:[self getCallNotificationCategory], [self getMessageNotificationCategory], nil];
[NSSet setWithObjects:[self getCallNotificationCategory], [self getMessageNotificationCategory], [self getAccountExpiryNotificationCategory], nil];
UIUserNotificationSettings *userSettings =
[UIUserNotificationSettings settingsForTypes:notifTypes categories:categories];
[app registerUserNotificationSettings:userSettings];
@ -224,6 +234,7 @@
}];
[LinphoneManager.instance startLinphoneCore];
LinphoneManager.instance.iapManager.notificationCategory = @"expiry_notification";
// initialize UI
[self.window makeKeyAndVisible];
[RootViewManager setupWithPortrait:(PhoneMainView *)self.window.rootViewController];
@ -357,6 +368,11 @@
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
LOGI(@"%@ - state = %ld", NSStringFromSelector(_cmd), (long)application.applicationState);
if ([notification.category isEqual:LinphoneManager.instance.iapManager.notificationCategory]){
[PhoneMainView.instance changeCurrentView:ShopView.compositeViewDescription];
return;
}
[self fixRing];

View file

@ -1741,6 +1741,7 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) {
LOGW(@"It seems that Linphone BG mode was deactivated, just skipping");
return;
}
[_iapManager check];
// kick up network cnx, just in case
[self refreshRegisters];
linphone_core_iterate(theLinphoneCore);
@ -2396,7 +2397,7 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) {
- (void)inappReady:(NSNotification *)notif {
// Query our in-app server to retrieve InApp purchases
[_iapManager retrievePurchases];
//[_iapManager retrievePurchases];
}
#pragma mark -

35
Classes/ShopView.h Normal file
View file

@ -0,0 +1,35 @@
/* AboutViewController.h
*
* Copyright (C) 2009 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import <UIKit/UIKit.h>
#import "UICompositeView.h"
@interface ShopView : TPMultiLayoutViewController <UICompositeViewDelegate>
@property(weak, nonatomic) IBOutlet UILabel *accountProductTitle;
@property(weak, nonatomic) IBOutlet UILabel *accountProductDescription;
@property(weak, nonatomic) IBOutlet UILabel *accountProductPrice;
@property(weak, nonatomic) IBOutlet UIButton *accountBuyButton;
- (IBAction)onLinkTap:(id)sender;
- (IBAction)onDialerBackClick:(id)sender;
- (IBAction)onPurchaseButtonClick:(id)sender;
@end

82
Classes/ShopView.m Normal file
View file

@ -0,0 +1,82 @@
/* AboutViewController.m
*
* Copyright (C) 2009 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import "PhoneMainView.h"
#import "ShopView.h"
#import "LinphoneManager.h"
#import "LinphoneIOSVersion.h"
@implementation ShopView
#pragma mark - UICompositeViewDelegate Functions
static UICompositeViewDescription *compositeDescription = nil;
+ (UICompositeViewDescription *)compositeViewDescription {
if (compositeDescription == nil) {
compositeDescription = [[UICompositeViewDescription alloc] init:self.class
statusBar:StatusBarView.class
tabBar:nil
sideMenu:SideMenuView.class
fullscreen:false
isLeftFragment:YES
fragmentWith:nil];
}
return compositeDescription;
}
- (UICompositeViewDescription *)compositeViewDescription {
return self.class.compositeViewDescription;
}
#pragma mark - ViewController Functions
- (void)viewDidLoad {
InAppProductsManager *aipm = LinphoneManager.instance.iapManager;
NSMutableArray *productsAvailable = aipm.productsAvailable;
if ( [productsAvailable count] > 0){
SKProduct *product = [productsAvailable objectAtIndex:0];
[_accountProductTitle setText:product.localizedTitle];
[_accountProductDescription setText:product.localizedDescription];
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
[numberFormatter setFormatterBehavior:NSNumberFormatterBehavior10_4];
[numberFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
[numberFormatter setLocale:product.priceLocale];
NSString *formattedString = [numberFormatter stringFromNumber:product.price];
[_accountProductPrice setText:formattedString];
}
[super viewDidLoad];
}
#pragma mark - Action Functions
- (IBAction)onLinkTap:(id)sender {
}
- (IBAction)onDialerBackClick:(id)sender {
[PhoneMainView.instance popToView:DialerView.compositeViewDescription];
}
- (IBAction)onPurchaseButtonClick:(id)sender {
[PhoneMainView.instance popToView:DialerView.compositeViewDescription];
}
@end

View file

@ -11,6 +11,8 @@
#import "PhoneMainView.h"
#import "StatusBarView.h"
#import "ShopView.h"
#import "LinphoneManager.h"
@implementation SideMenuEntry
@ -47,6 +49,14 @@
[PhoneMainView.instance
changeCurrentView:SettingsView.compositeViewDescription];
}]];
InAppProductsManager *iapm = LinphoneManager.instance.iapManager;
if (iapm.enabled){
[_sideMenuEntries addObject:[[SideMenuEntry alloc] initWithTitle:NSLocalizedString(@"Shop", nil)
tapBlock:^() {
[PhoneMainView.instance
changeCurrentView:ShopView.compositeViewDescription];
}]];
}
[_sideMenuEntries addObject:[[SideMenuEntry alloc] initWithTitle:NSLocalizedString(@"About", nil)
tapBlock:^() {
[PhoneMainView.instance

View file

@ -0,0 +1,30 @@
/* Class = "UIButton"; accessibilityLabel = "Add contact"; ObjectID = "ETk-tB-ZNl"; */
"ETk-tB-ZNl.accessibilityLabel" = "Add contact";
/* Class = "UILabel"; text = "GNU General Public License V2\n© 2010-2016 Belledonne Communications"; ObjectID = "ToT-OI-B2F"; */
"ToT-OI-B2F.text" = "GNU General Public License V2\n© 2010-2016 Belledonne Communications";
/* Class = "UILabel"; text = "Label"; ObjectID = "Ui2-bF-EnK"; */
"Ui2-bF-EnK.text" = "Label";
/* Class = "UILabel"; text = "LINPHONE"; ObjectID = "fss-Tl-kRy"; */
"fss-Tl-kRy.text" = "LINPHONE";
/* Class = "UILabel"; text = "Linphone Core 3.9.0"; ObjectID = "g2W-u5-yxg"; */
"g2W-u5-yxg.text" = "Linphone Core 3.9.0";
/* Class = "UILabel"; text = "SHOP"; ObjectID = "iNt-9d-7si"; */
"iNt-9d-7si.text" = "SHOP";
/* Class = "UILabel"; text = "Linphone iPhone 3.0"; ObjectID = "oYk-ih-BBi"; */
"oYk-ih-BBi.text" = "Linphone iPhone 3.0";
/* Class = "UILabel"; text = "https://www.linphone.org"; ObjectID = "uis-xz-Qsa"; */
"uis-xz-Qsa.text" = "https://www.linphone.org";
/* Class = "UIButton"; accessibilityLabel = "Add contact"; ObjectID = "vX8-wO-ZEN"; */
"vX8-wO-ZEN.accessibilityLabel" = "Add contact";
/* Class = "UILabel"; text = "ABOUT"; ObjectID = "wKp-iH-ojJ"; */
"wKp-iH-ojJ.text" = "ABOUT";

View file

@ -0,0 +1,30 @@
/* Class = "UIButton"; accessibilityLabel = "Add contact"; ObjectID = "ETk-tB-ZNl"; */
"ETk-tB-ZNl.accessibilityLabel" = "Add contact";
/* Class = "UILabel"; text = "GNU General Public License V2\n© 2010-2016 Belledonne Communications"; ObjectID = "ToT-OI-B2F"; */
"ToT-OI-B2F.text" = "GNU General Public License V2\n© 2010-2016 Belledonne Communications";
/* Class = "UILabel"; text = "Purchase"; ObjectID = "Ui2-bF-EnK"; */
"Ui2-bF-EnK.text" = "Purchase";
/* Class = "UILabel"; text = "LINPHONE"; ObjectID = "fss-Tl-kRy"; */
"fss-Tl-kRy.text" = "LINPHONE";
/* Class = "UILabel"; text = "Linphone Core 3.9.0"; ObjectID = "g2W-u5-yxg"; */
"g2W-u5-yxg.text" = "Linphone Core 3.9.0";
/* Class = "UILabel"; text = "SHOP"; ObjectID = "iNt-9d-7si"; */
"iNt-9d-7si.text" = "SHOP";
/* Class = "UILabel"; text = "Linphone iPhone 3.0"; ObjectID = "oYk-ih-BBi"; */
"oYk-ih-BBi.text" = "Linphone iPhone 3.0";
/* Class = "UILabel"; text = "https://www.linphone.org"; ObjectID = "uis-xz-Qsa"; */
"uis-xz-Qsa.text" = "https://www.linphone.org";
/* Class = "UIButton"; accessibilityLabel = "Add contact"; ObjectID = "vX8-wO-ZEN"; */
"vX8-wO-ZEN.accessibilityLabel" = "Add contact";
/* Class = "UILabel"; text = "ABOUT"; ObjectID = "wKp-iH-ojJ"; */
"wKp-iH-ojJ.text" = "ABOUT";

View file

@ -1,4 +1,12 @@
[app]
#Hide in the assistant the button to configure an external SIP account.
hide_assistant_custom_account=0
#Hide in the assistant the button to create a new SIP account
hide_assistant_create_account=0
#contact_display_username_only=1
#contact_filter_on_default_domain=1
#debug_popup_magic=**00**
@ -11,15 +19,42 @@ publish_presence=0
password_length=-1
username_length=-1
[in_app_purchase]
#set to 1 if in-app purchases are to be shown in the application
enabled=0
#specify here the id of the sip account in-app purchase service to be shown in the shop section of the app
paid_account_id=sipAccount_12m
#the url of the inapp/account management server, for submitting the receipt and validating the account.
receipt_validation_url=https://www.linphone.org/inapp.php
#for future use, to specify the full list of paying services to show in the shop view
products_list=sipAccount_12m
#minimum period of time between notifications to the user about his expiring/expired account, in seconds.
expiry_check_period=30
#period of time before account expiry, to start notifying the user about expiration arriving, in seconds.
warn_before_expiry_period=160
#for test only, simulate an account expiry after the specified number of seconds
expiry_time_test=180
[sip]
sip_random_port=0
[misc]
#by default it is set to 30 by liblinphone
history_max_size=-1
[sip]
sip_random_port=0
#whether SIP passwords are to be encrypted in configuration storage file
store_ha1_passwd=0
#handle_content_encoding=none
[sound]
dtmf_player_amp=0.007
echocancellation=0
@ -28,4 +63,4 @@ eq_location=mic
ringer_dev_id=AQ: Audio Queue Device
[video]
display_filter_auto_rotate=0
display_filter_auto_rotate=0

20
doc/CUSTOMIZING.txt Normal file
View file

@ -0,0 +1,20 @@
# Assistant configuration
The assistant allows to create a new sip account on a pre-defined SIP service using an xml-rpc connection,
as well as configuring an existing SIP account.
The files Resources/assistant_linphone_create.rc and Resources/assistant_linphone_existing.rc contain the
information necessary to create and configure the SIP accounts, most notabily:
* proxy_default_values/reg_identity to define the SIP identity
* sip/rls_uri to define the SIP URI of the presence server
* assistant/domain to specify the SIP domain
* assistant/xmlrpc_url to specify the https url of the account creation service
# In-app purchase configuration
The Resources/linphonerc.factory, section [in_app_purchase] is the entry point for configuring
the in-app purchases available in the application, as well as parameters for account expiry notifications.
Refer to the inlined comments in this configuration for description of all configurables.

View file

@ -40,6 +40,9 @@
34216F401547EBCD00EA9777 /* VideoZoomHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 34216F3F1547EBCD00EA9777 /* VideoZoomHandler.m */; };
344ABDF114850AE9007420B6 /* libc++.1.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 344ABDEF14850AE9007420B6 /* libc++.1.dylib */; settings = {ATTRIBUTES = (Weak, ); }; };
344ABDF214850AE9007420B6 /* libstdc++.6.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 344ABDF014850AE9007420B6 /* libstdc++.6.dylib */; settings = {ATTRIBUTES = (Weak, ); }; };
570742581D5A0691004B9C84 /* ShopView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 570742561D5A0691004B9C84 /* ShopView.xib */; };
570742611D5A09B8004B9C84 /* ShopView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5707425F1D5A09B8004B9C84 /* ShopView.m */; };
570742671D5A63DB004B9C84 /* StoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 570742661D5A63DB004B9C84 /* StoreKit.framework */; };
630589E71B4E810900EFAE36 /* ChatTester.m in Sources */ = {isa = PBXBuildFile; fileRef = 630589DF1B4E810900EFAE36 /* ChatTester.m */; };
630589E81B4E810900EFAE36 /* ContactsTester.m in Sources */ = {isa = PBXBuildFile; fileRef = 630589E11B4E810900EFAE36 /* ContactsTester.m */; };
630589EA1B4E810900EFAE36 /* LinphoneTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 630589E41B4E810900EFAE36 /* LinphoneTestCase.m */; };
@ -934,6 +937,12 @@
34216F3F1547EBCD00EA9777 /* VideoZoomHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = VideoZoomHandler.m; path = LinphoneUI/VideoZoomHandler.m; sourceTree = "<group>"; };
344ABDEF14850AE9007420B6 /* libc++.1.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = "libc++.1.dylib"; path = "usr/lib/libc++.1.dylib"; sourceTree = SDKROOT; };
344ABDF014850AE9007420B6 /* libstdc++.6.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = "libstdc++.6.dylib"; path = "usr/lib/libstdc++.6.dylib"; sourceTree = SDKROOT; };
570742571D5A0691004B9C84 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/ShopView.xib; sourceTree = "<group>"; };
5707425F1D5A09B8004B9C84 /* ShopView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ShopView.m; sourceTree = "<group>"; };
570742601D5A09B8004B9C84 /* ShopView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ShopView.h; sourceTree = "<group>"; };
570742631D5A1860004B9C84 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/ShopView.strings; sourceTree = "<group>"; };
570742651D5A1868004B9C84 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/ShopView.strings; sourceTree = "<group>"; };
570742661D5A63DB004B9C84 /* StoreKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = StoreKit.framework; path = System/Library/Frameworks/StoreKit.framework; sourceTree = SDKROOT; };
630589DE1B4E810900EFAE36 /* ChatTester.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ChatTester.h; sourceTree = "<group>"; };
630589DF1B4E810900EFAE36 /* ChatTester.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ChatTester.m; sourceTree = "<group>"; };
630589E01B4E810900EFAE36 /* ContactsTester.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContactsTester.h; sourceTree = "<group>"; };
@ -1814,6 +1823,7 @@
63CFEE0A1B9EDD88007EA5BD /* libmssilk.a in Frameworks */,
63CFEE0B1B9EDD88007EA5BD /* libmswebrtc.a in Frameworks */,
63CFEE0C1B9EDD88007EA5BD /* libmsx264.a in Frameworks */,
570742671D5A63DB004B9C84 /* StoreKit.framework in Frameworks */,
63CFEDF61B9EDD74007EA5BD /* libopencore-amrnb.a in Frameworks */,
63CFEDF71B9EDD74007EA5BD /* libopencore-amrwb.a in Frameworks */,
63CFEDF81B9EDD74007EA5BD /* libopenh264.a in Frameworks */,
@ -1935,7 +1945,10 @@
children = (
22E0A81D111C44E100B04932 /* AboutView.h */,
22E0A81C111C44E100B04932 /* AboutView.m */,
5707425F1D5A09B8004B9C84 /* ShopView.m */,
570742601D5A09B8004B9C84 /* ShopView.h */,
636316D31A1DEBCB0009B839 /* AboutView.xib */,
570742561D5A0691004B9C84 /* ShopView.xib */,
D350F20B15A43BB100149E54 /* AssistantView.h */,
D350F20C15A43BB100149E54 /* AssistantView.m */,
D38187E015FE348A00C3EDCA /* AssistantView.xib */,
@ -2171,6 +2184,7 @@
29B97323FDCFA39411CA2CEA /* Frameworks */ = {
isa = PBXGroup;
children = (
570742661D5A63DB004B9C84 /* StoreKit.framework */,
636920661D253DF700D44CAC /* libbcunit.a */,
637835A41CFD971D00599382 /* libbv16.a */,
63FD3F061CA17F9100E9AECC /* libmbedcrypto.a */,
@ -3106,7 +3120,10 @@
DevelopmentTeam = Z2V957B3D6;
SystemCapabilities = {
com.apple.InAppPurchase = {
enabled = 0;
enabled = 1;
};
com.apple.Push = {
enabled = 1;
};
};
};
@ -3702,6 +3719,7 @@
633FEE121D3CD5590014B822 /* chat_message_not_delivered.png in Resources */,
633FEDCE1D3CD5590014B822 /* call_quality_indicator_1.png in Resources */,
633FEF4E1D3CD55A0014B822 /* valid_default.png in Resources */,
570742581D5A0691004B9C84 /* ShopView.xib in Resources */,
633FEE361D3CD5590014B822 /* conference_exit_over.png in Resources */,
633FEDAA1D3CD5590014B822 /* backspace_disabled.png in Resources */,
F0938159188E629800A55DFA /* iTunesArtwork in Resources */,
@ -3858,6 +3876,7 @@
63B81A101B57DA33009604A6 /* UIScrollView+TPKeyboardAvoidingAdditions.m in Sources */,
F03CA84318C72F1A0008889D /* UITextViewNoDefine.m in Sources */,
63B81A0D1B57DA33009604A6 /* TPKeyboardAvoidingCollectionView.m in Sources */,
570742611D5A09B8004B9C84 /* ShopView.m in Sources */,
63F1DF4F1BCE985F00EDED90 /* UICallConferenceCell.m in Sources */,
D37DC6C11594AE1800B2A5EB /* LinphoneCoreSettingsStore.m in Sources */,
63CD4B4F1A5AAC8C00B84282 /* DTAlertView.m in Sources */,
@ -3983,6 +4002,16 @@
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
570742561D5A0691004B9C84 /* ShopView.xib */ = {
isa = PBXVariantGroup;
children = (
570742571D5A0691004B9C84 /* Base */,
570742631D5A1860004B9C84 /* en */,
570742651D5A1868004B9C84 /* fr */,
);
name = ShopView.xib;
sourceTree = "<group>";
};
63058A0F1B4E821E00EFAE36 /* InfoPlist.strings */ = {
isa = PBXVariantGroup;
children = (
@ -4445,7 +4474,6 @@
"-Werror=objc-method-access",
"-Werror=incomplete-implementation",
"-Wno-error-deprecated",
"-DLINPHONE_CAPABILITY_INAPP_PURCHASE=0",
);
};
name = Debug;
@ -4533,7 +4561,6 @@
"-Werror=objc-method-access",
"-Werror=incomplete-implementation",
"-Wno-error-deprecated",
"-DLINPHONE_CAPABILITY_INAPP_PURCHASE=0",
);
};
name = DistributionAdhoc;
@ -4620,7 +4647,6 @@
"-Werror=objc-method-access",
"-Werror=incomplete-implementation",
"-Wno-error-deprecated",
"-DLINPHONE_CAPABILITY_INAPP_PURCHASE=0",
);
};
name = Release;
@ -4708,7 +4734,6 @@
"-Werror=objc-method-access",
"-Werror=incomplete-implementation",
"-Wno-error-deprecated",
"-DLINPHONE_CAPABILITY_INAPP_PURCHASE=0",
);
};
name = Distribution;