InAppProducts: add in app feature

This commit is contained in:
Gautier Pelloux-Prayer 2015-04-15 12:53:57 +02:00
parent d8dcaa19c1
commit 9c1eb3335a
6 changed files with 150 additions and 21 deletions

View file

@ -0,0 +1,27 @@
/* InAppProductsManager.h
*
* Copyright (C) 2012 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 <Foundation/Foundation.h>
#import <StoreKit/StoreKit.h>
@interface InAppProductsManager : NSObject <SKProductsRequestDelegate, SKPaymentTransactionObserver> {
NSArray *inAppProducts;
}
@end

View file

@ -0,0 +1,66 @@
/* InAppProductsManager.h
*
* Copyright (C) 2012 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 "InAppProductsManager.h"
#import "Utils.h"
@implementation InAppProductsManager {
bool ready;
}
- (instancetype)init {
if ((self = [super init]) != nil) {
[self loadProducts];
ready = false;
}
return self;
}
- (void)loadProducts {
if (! [SKPaymentQueue canMakePayments]) {
return;
}
NSURL *url = [[NSBundle mainBundle] URLForResource:@"in_app_products"
withExtension:@"plist"];
inAppProducts = [NSArray arrayWithContentsOfURL:url];
SKProductsRequest *productsRequest = [[SKProductsRequest alloc]
initWithProductIdentifiers:[NSSet setWithArray:inAppProducts]];
productsRequest.delegate = self;
[productsRequest start];
}
- (void)productsRequest:(SKProductsRequest *)request
didReceiveResponse:(SKProductsResponse *)response {
inAppProducts = response.products;
LOGI(@"Found %lu products purchasable", inAppProducts.count);
for (NSString *invalidIdentifier in response.invalidProductIdentifiers) {
LOGE(@"Product Identifier with invalid ID %@", invalidIdentifier);
}
ready = true;
}
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions {
}
@end

View file

@ -31,6 +31,7 @@
#import "IASKAppSettingsViewController.h"
#import "FastAddressBook.h"
#import "Utils.h"
#import "InAppProductsManager.h"
#include "linphone/linphonecore.h"
#include "linphone/linphone_tunnel.h"
@ -202,6 +203,6 @@ typedef struct _LinphoneManagerSounds {
@property (copy) void (^silentPushCompletion)(UIBackgroundFetchResult);
@property (readonly) BOOL wasRemoteProvisioned;
@property (readonly) LpConfig *configDb;
@property (readonly) InAppProductsManager *iapManager;
@end

View file

@ -466,7 +466,7 @@ exit_dbmigration:
if( configDb == nil ) return;
if( lp_config_get_int(configDb, LINPHONERC_APPLICATION_KEY, migration_flag, 0) ){
Linphone_log(@"UserPrefs migration already performed, skip");
LOGI(@"UserPrefs migration already performed, skip");
return;
}
@ -477,11 +477,11 @@ exit_dbmigration:
@"start_at_boot_preference" :@YES};
BOOL shouldSync = FALSE;
Linphone_log(@"%lu user prefs", (unsigned long)[defaults_keys count]);
LOGI(@"%lu user prefs", (unsigned long)[defaults_keys count]);
for( NSString* userpref in values ){
if( [defaults_keys containsObject:userpref] ){
Linphone_log(@"Migrating %@ from user preferences: %d", userpref, [[defaults objectForKey:userpref] boolValue]);
LOGI(@"Migrating %@ from user preferences: %d", userpref, [[defaults objectForKey:userpref] boolValue]);
lp_config_set_int(configDb, LINPHONERC_APPLICATION_KEY, [userpref UTF8String], [[defaults objectForKey:userpref] boolValue]);
[[NSUserDefaults standardUserDefaults] removeObjectForKey:userpref];
shouldSync = TRUE;
@ -492,7 +492,7 @@ exit_dbmigration:
}
if( shouldSync ){
Linphone_log(@"Synchronizing...");
LOGI(@"Synchronizing...");
[[NSUserDefaults standardUserDefaults] synchronize];
}
// don't get back here in the future
@ -985,7 +985,7 @@ static void linphone_iphone_is_composing_received(LinphoneCore *lc, LinphoneChat
+ (void)kickOffNetworkConnection {
static BOOL in_progress = FALSE;
if( in_progress ){
Linphone_warn(@"Connection kickoff already in progress");
LOGW(@"Connection kickoff already in progress");
return;
}
in_progress = TRUE;
@ -1003,7 +1003,7 @@ static void linphone_iphone_is_composing_received(LinphoneCore *lc, LinphoneChat
time_t loop_time;
if( res == FALSE ){
Linphone_log(@"Could not open write stream, backing off");
LOGI(@"Could not open write stream, backing off");
CFRelease(writeStream);
in_progress = FALSE;
return;
@ -1027,10 +1027,10 @@ static void linphone_iphone_is_composing_received(LinphoneCore *lc, LinphoneChat
CFWriteStreamWrite (writeStream,(const UInt8*)buff,strlen(buff));
} else if( !timeout_reached ){
CFErrorRef error = CFWriteStreamCopyError(writeStream);
Linphone_dbg(@"CFStreamError: %@", error);
LOGD(@"CFStreamError: %@", error);
CFRelease(error);
} else if( timeout_reached ){
Linphone_log(@"CFStream timeout reached");
LOGI(@"CFStream timeout reached");
}
CFWriteStreamClose (writeStream);
CFRelease(writeStream);
@ -1283,6 +1283,7 @@ static LinphoneCoreVTable linphonec_vtable = {
[_contactSipField release];
_contactSipField = [[self lpConfigStringForKey:@"contact_im_type_value" withDefault:@"SIP"] retain];
_iapManager = [[InAppProductsManager alloc] init];
fastAddressBook = [[FastAddressBook alloc] init];
@ -1313,7 +1314,7 @@ static LinphoneCoreVTable linphonec_vtable = {
const char* addr = linphone_proxy_config_get_addr(proxy);
// we want to enable AVPF for the proxies
if( addr && strstr(addr, "sip.linphone.org") != 0 ){
Linphone_log(@"Migrating proxy config to use AVPF");
LOGI(@"Migrating proxy config to use AVPF");
linphone_proxy_config_enable_avpf(proxy, TRUE);
}
proxies = proxies->next;
@ -1328,7 +1329,7 @@ static LinphoneCoreVTable linphonec_vtable = {
const char* addr = linphone_proxy_config_get_addr(proxy);
// we want to enable quality reporting for the proxies that are on linphone.org
if( addr && strstr(addr, "sip.linphone.org") != 0 ){
Linphone_log(@"Migrating proxy config to send quality report");
LOGI(@"Migrating proxy config to send quality report");
linphone_proxy_config_set_quality_reporting_collector(proxy, "sip:voip-metrics@sip.linphone.org");
linphone_proxy_config_set_quality_reporting_interval(proxy, 180);
linphone_proxy_config_enable_quality_reporting(proxy, TRUE);
@ -1560,7 +1561,7 @@ static int comp_call_id(const LinphoneCall* call , const char *callid) {
//first, make sure this callid is not already involved in a call
MSList* calls = (MSList*)linphone_core_get_calls(theLinphoneCore);
if (ms_list_find_custom(calls, (MSCompareFunc)comp_call_id, [callid UTF8String])) {
Linphone_warn(@"Call id [%@] already handled",callid);
LOGW(@"Call id [%@] already handled",callid);
return;
};
if ([pushCallIDs count] > 10 /*max number of pending notif*/)
@ -1588,7 +1589,7 @@ static int comp_call_id(const LinphoneCall* call , const char *callid) {
- (void)playMessageSound {
BOOL success = [self.messagePlayer play];
if( !success ){
Linphone_err(@"Could not play the message sound");
LOGE(@"Could not play the message sound");
}
AudioServicesPlaySystemSound([LinphoneManager instance].sounds.vibrate);
}

7
in_app_products.plist Normal file
View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
<string>test.tunnel</string>
</array>
</plist>

View file

@ -122,6 +122,9 @@
639CEB061A1DF4F1004DE38F /* UIChatRoomCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 639CEB081A1DF4F1004DE38F /* UIChatRoomCell.xib */; };
639CEB091A1DF4FA004DE38F /* UIChatCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 639CEB0B1A1DF4FA004DE38F /* UIChatCell.xib */; };
63CD4B4F1A5AAC8C00B84282 /* DTAlertView.m in Sources */ = {isa = PBXBuildFile; fileRef = 63CD4B4E1A5AAC8C00B84282 /* DTAlertView.m */; };
63E59A3A1ADE6A0100646FB3 /* StoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 63E59A391ADE6A0100646FB3 /* StoreKit.framework */; };
63E59A3C1ADE6E5C00646FB3 /* in_app_products.plist in Resources */ = {isa = PBXBuildFile; fileRef = 63E59A3B1ADE6E5C00646FB3 /* in_app_products.plist */; };
63E59A3F1ADE70D900646FB3 /* InAppProductsManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 63E59A3E1ADE70D900646FB3 /* InAppProductsManager.m */; };
63FB30351A680E73008CA393 /* UIRoundedImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 63FB30341A680E73008CA393 /* UIRoundedImageView.m */; };
70571E1A13FABCB000CDD3C2 /* rootca.pem in Resources */ = {isa = PBXBuildFile; fileRef = 70571E1913FABCB000CDD3C2 /* rootca.pem */; };
7066FC0C13E830E400EFC6DC /* libvpx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7066FC0B13E830E400EFC6DC /* libvpx.a */; };
@ -1036,6 +1039,10 @@
639CEB0D1A1DF52C004DE38F /* ru */ = {isa = PBXFileReference; fileEncoding = 2483028224; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/UICallCell.strings; sourceTree = "<group>"; };
63CD4B4D1A5AAC8C00B84282 /* DTAlertView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DTAlertView.h; sourceTree = "<group>"; };
63CD4B4E1A5AAC8C00B84282 /* DTAlertView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DTAlertView.m; sourceTree = "<group>"; };
63E59A391ADE6A0100646FB3 /* StoreKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = StoreKit.framework; path = System/Library/Frameworks/StoreKit.framework; sourceTree = SDKROOT; };
63E59A3B1ADE6E5C00646FB3 /* in_app_products.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = in_app_products.plist; sourceTree = "<group>"; };
63E59A3D1ADE6ECB00646FB3 /* InAppProductsManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InAppProductsManager.h; sourceTree = "<group>"; };
63E59A3E1ADE70D900646FB3 /* InAppProductsManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = InAppProductsManager.m; sourceTree = "<group>"; };
63EF7FDC1A24B5810017A416 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/AboutViewController.strings; sourceTree = "<group>"; };
63FB30331A680E73008CA393 /* UIRoundedImageView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIRoundedImageView.h; sourceTree = "<group>"; };
63FB30341A680E73008CA393 /* UIRoundedImageView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIRoundedImageView.m; sourceTree = "<group>"; };
@ -1893,6 +1900,7 @@
D37EE10916032DA4003608A6 /* libmediastreamer_base.a in Frameworks */,
D37EE10A16032DA4003608A6 /* libmediastreamer_voip.a in Frameworks */,
226F2ED81344B0EF00F6EF27 /* libmsamr.a in Frameworks */,
63E59A3A1ADE6A0100646FB3 /* StoreKit.framework in Frameworks */,
223148E61178A09900637D6A /* libmsilbc.a in Frameworks */,
226183B0147259670037138E /* libmssilk.a in Frameworks */,
22AA8AFE13D7125600B30535 /* libmsx264.a in Frameworks */,
@ -2035,6 +2043,8 @@
22405EFD1601C19000B92522 /* ImageViewController.h */,
22405EFE1601C19100B92522 /* ImageViewController.m */,
D37EE11016035793003608A6 /* ImageViewController.xib */,
63E59A3D1ADE6ECB00646FB3 /* InAppProductsManager.h */,
63E59A3E1ADE70D900646FB3 /* InAppProductsManager.m */,
D31AAF5C159B3919002C6B02 /* InCallTableViewController.h */,
D31AAF5D159B3919002C6B02 /* InCallTableViewController.m */,
D3F83EE91582021700336684 /* InCallViewController.h */,
@ -2230,6 +2240,7 @@
F0B89C2518DC973E0050B60E /* wizard_linphone_create.rc */,
F0B89C2618DC973E0050B60E /* wizard_linphone_existing.rc */,
F0B89C2718DC973E0050B60E /* wizard_remote.rc */,
63E59A3B1ADE6E5C00646FB3 /* in_app_products.plist */,
);
name = Resources;
sourceTree = "<group>";
@ -2237,6 +2248,7 @@
29B97323FDCFA39411CA2CEA /* Frameworks */ = {
isa = PBXGroup;
children = (
63E59A391ADE6A0100646FB3 /* StoreKit.framework */,
F0FF66AA1ACAEEB0008A4486 /* IOKit.framework */,
F0B026F21AA710AF00FF49F7 /* libiconv.dylib */,
F05BAA611A5D594E00411815 /* libz.dylib */,
@ -3184,6 +3196,11 @@
TargetAttributes = {
1D6058900D05DD3D006BFB54 = {
DevelopmentTeam = Z2V957B3D6;
SystemCapabilities = {
com.apple.InAppPurchase = {
enabled = 1;
};
};
};
F08F118319C09C6A007D70C2 = {
DevelopmentTeam = Z2V957B3D6;
@ -3351,6 +3368,7 @@
D3F83F5A1582223B00336684 /* numpad_five_over.png in Resources */,
D3F83F5C1582223B00336684 /* numpad_six_default.png in Resources */,
636316D91A1DECC90009B839 /* PhoneMainView.xib in Resources */,
63E59A3C1ADE6E5C00646FB3 /* in_app_products.plist in Resources */,
D3F83F5E1582223B00336684 /* numpad_six_over.png in Resources */,
D3F83F601582223B00336684 /* numpad_seven_default.png in Resources */,
D3F83F621582223B00336684 /* numpad_seven_over.png in Resources */,
@ -3993,6 +4011,7 @@
D37C639515AADDAF009D0BAC /* UIContactDetailsHeader.m in Sources */,
D37C639B15AADEF6009D0BAC /* ContactDetailsTableViewController.m in Sources */,
636316DE1A1DEF2F0009B839 /* UIButtonShrinkable.m in Sources */,
63E59A3F1ADE70D900646FB3 /* InAppProductsManager.m in Sources */,
D3C6526715AC1A8F0092A874 /* UIEditableTableViewCell.m in Sources */,
D378906515AC373B00BD776C /* ContactDetailsLabelViewController.m in Sources */,
D3E8F68615ADE05B0065A226 /* UIContactDetailsFooter.m in Sources */,
@ -4515,6 +4534,7 @@
ARCHS = "$(ARCHS_STANDARD)";
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
CLANG_WARN_UNREACHABLE_CODE = NO;
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COMPRESS_PNG_FILES = NO;
@ -4533,7 +4553,8 @@
DEBUG,
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_TREAT_WARNINGS_AS_ERRORS = NO;
GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
HEADER_SEARCH_PATHS = (
"$(SRCROOT)/liblinphone-sdk/apple-darwin/include",
"$(SRCROOT)/Classes/Utils/NinePatch/",
@ -4599,9 +4620,10 @@
ARCHS = "$(ARCHS_STANDARD)";
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
CLANG_WARN_UNREACHABLE_CODE = NO;
CODE_SIGN_ENTITLEMENTS = "";
CODE_SIGN_IDENTITY = "iPhone Distribution";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COMPRESS_PNG_FILES = NO;
COPY_PHASE_STRIP = NO;
FRAMEWORK_SEARCH_PATHS = "";
@ -4617,7 +4639,8 @@
HAVE_OPENH264,
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_TREAT_WARNINGS_AS_ERRORS = NO;
GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
HEADER_SEARCH_PATHS = (
"$(SRCROOT)/liblinphone-sdk/apple-darwin/include",
"$(SRCROOT)/Classes/Utils/NinePatch/",
@ -4683,6 +4706,7 @@
ARCHS = "$(ARCHS_STANDARD)";
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
CLANG_WARN_UNREACHABLE_CODE = NO;
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COMPRESS_PNG_FILES = NO;
@ -4699,7 +4723,8 @@
HAVE_SSL,
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_TREAT_WARNINGS_AS_ERRORS = NO;
GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
HEADER_SEARCH_PATHS = (
"$(SRCROOT)/liblinphone-sdk/apple-darwin/include",
"$(SRCROOT)/Classes/Utils/NinePatch/",
@ -4765,9 +4790,10 @@
ARCHS = "$(ARCHS_STANDARD)";
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
CLANG_WARN_UNREACHABLE_CODE = NO;
CODE_SIGN_ENTITLEMENTS = "";
CODE_SIGN_IDENTITY = "iPhone Distribution";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COMPRESS_PNG_FILES = NO;
COPY_PHASE_STRIP = NO;
FRAMEWORK_SEARCH_PATHS = "";
@ -4782,7 +4808,8 @@
HAVE_SSL,
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_TREAT_WARNINGS_AS_ERRORS = NO;
GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
HEADER_SEARCH_PATHS = (
"$(SRCROOT)/liblinphone-sdk/apple-darwin/include",
"$(SRCROOT)/Classes/Utils/NinePatch/",