diff options
Diffstat (limited to 'platform/iphone')
-rw-r--r-- | platform/iphone/SCsub | 3 | ||||
-rw-r--r-- | platform/iphone/app_delegate.mm | 45 | ||||
-rw-r--r-- | platform/iphone/detect.py | 27 | ||||
-rwxr-xr-x | platform/iphone/gl_view.h | 2 | ||||
-rwxr-xr-x | platform/iphone/gl_view.mm | 2 | ||||
-rw-r--r-- | platform/iphone/icloud.h | 66 | ||||
-rw-r--r-- | platform/iphone/icloud.mm | 379 | ||||
-rw-r--r-- | platform/iphone/in_app_store.mm | 9 | ||||
-rw-r--r-- | platform/iphone/os_iphone.cpp | 6 | ||||
-rw-r--r-- | platform/iphone/os_iphone.h | 6 | ||||
-rw-r--r-- | platform/iphone/view_controller.mm | 2 |
11 files changed, 537 insertions, 10 deletions
diff --git a/platform/iphone/SCsub b/platform/iphone/SCsub index d495e3b5fc..922a324694 100644 --- a/platform/iphone/SCsub +++ b/platform/iphone/SCsub @@ -12,6 +12,7 @@ iphone_lib = [ 'view_controller.mm', 'game_center.mm', 'in_app_store.mm', + 'icloud.mm', 'Appirater.m', ] @@ -34,5 +35,5 @@ obj = env_ios.Object('godot_iphone.cpp') prog = None prog = env_ios.Program('#bin/godot', [obj] + iphone_lib) -action = "dsymutil "+File(prog)[0].path+" -o " + File(prog)[0].path + ".dSYM" +action = "$IPHONEPATH/usr/bin/dsymutil "+File(prog)[0].path+" -o " + File(prog)[0].path + ".dSYM" env.AddPostAction(prog, action) diff --git a/platform/iphone/app_delegate.mm b/platform/iphone/app_delegate.mm index 3c79137171..d5764b2b5c 100644 --- a/platform/iphone/app_delegate.mm +++ b/platform/iphone/app_delegate.mm @@ -43,6 +43,11 @@ #import <AdSupport/AdSupport.h> #endif +#ifdef MODULE_PARSE_ENABLED +#import <Parse/Parse.h> +#import "FBSDKCoreKit/FBSDKCoreKit.h" +#endif + #define kFilteringFactor 0.1 #define kRenderingFrequency 60 #define kAccelerometerFrequency 100.0 // Hz @@ -139,8 +144,9 @@ static int frame_count = 0; ++frame_count; // this might be necessary before here - for (NSString* key in [[NSBundle mainBundle] infoDictionary]) { - NSObject* value = [[[NSBundle mainBundle] infoDictionary] objectForKey:key]; + NSDictionary* dict = [[NSBundle mainBundle] infoDictionary]; + for (NSString* key in dict) { + NSObject* value = [dict objectForKey:key]; String ukey = String::utf8([key UTF8String]); // we need a NSObject to Variant conversor @@ -341,6 +347,15 @@ static int frame_count = 0; // For 4.2+ support - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { +#ifdef MODULE_PARSE_ENABLED + NSLog(@"Handling application openURL"); + return [[FBSDKApplicationDelegate sharedInstance] application:application + openURL:url + sourceApplication:sourceApplication + annotation:annotation]; +#endif + + #ifdef MODULE_FACEBOOKSCORER_IOS_ENABLED return [[[FacebookScorer sharedInstance] facebook] handleOpenURL:url]; #else @@ -348,6 +363,32 @@ static int frame_count = 0; #endif } +- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { +#ifdef MODULE_PARSE_ENABLED + // Store the deviceToken in the current installation and save it to Parse. + PFInstallation *currentInstallation = [PFInstallation currentInstallation]; + //NSString* token = [[NSString alloc] initWithData:deviceToken encoding:NSUTF8StringEncoding]; + NSLog(@"Device Token : %@ ", deviceToken); + [currentInstallation setDeviceTokenFromData:deviceToken]; + [currentInstallation saveInBackground]; +#endif +} + +- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo { +#ifdef MODULE_PARSE_ENABLED + [PFPush handlePush:userInfo]; + NSDictionary *aps = [userInfo objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey]; + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + + NSLog(@"Push Notification Payload (app active) %@", aps); + [defaults setObject:aps forKey:@"notificationInfo"]; + [defaults synchronize]; + if (application.applicationState == UIApplicationStateInactive) { + [PFAnalytics trackAppOpenedWithRemoteNotificationPayload:userInfo]; + } +#endif +} + - (void)dealloc { [window release]; diff --git a/platform/iphone/detect.py b/platform/iphone/detect.py index fb57876a83..137fcc56f5 100644 --- a/platform/iphone/detect.py +++ b/platform/iphone/detect.py @@ -11,7 +11,8 @@ def get_name(): def can_build(): import sys - if sys.platform == 'darwin': + import os + if sys.platform == 'darwin' or os.environ.has_key("OSXCROSS_IOS"): return True return False @@ -25,9 +26,11 @@ def get_opts(): ('IPHONESDK', 'path to the iphone SDK', '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/${IOS_SDK_VERSION}.sdk/'), ('game_center', 'Support for game center', 'yes'), ('store_kit', 'Support for in-app store', 'yes'), + ('icloud', 'Support for iCloud', 'yes'), ('ios_gles22_override', 'Force GLES2.0 on iOS', 'yes'), ('ios_appirater', 'Enable Appirater', 'no'), ('ios_exceptions', 'Use exceptions when compiling on playbook', 'yes'), + ('ios_triple', 'Triple for ios toolchain', ''), ] def get_flags(): @@ -48,9 +51,10 @@ def configure(env): # env['CC'] = '$IPHONEPATH/Developer/usr/bin/gcc' # env['CXX'] = '$IPHONEPATH/Developer/usr/bin/g++' - env['CC'] = '$IPHONEPATH/usr/bin/clang' - env['CXX'] = '$IPHONEPATH/usr/bin/clang++' - env['AR'] = 'ar' + env['CC'] = '$IPHONEPATH/usr/bin/${ios_triple}clang' + env['CXX'] = '$IPHONEPATH/usr/bin/${ios_triple}clang++' + env['AR'] = '$IPHONEPATH/usr/bin/${ios_triple}ar' + env['RANLIB'] = '$IPHONEPATH/usr/bin/${ios_triple}ranlib' import string if (env["bits"]=="64"): @@ -59,7 +63,7 @@ def configure(env): env.Append(CPPFLAGS=['-DNEED_LONG_INT']) env.Append(CPPFLAGS=['-DLIBYUV_DISABLE_NEON']) else: - env['CCFLAGS'] = string.split('-fno-objc-arc -arch armv7 -fmessage-length=0 -fno-strict-aliasing -fdiagnostics-print-source-range-info -fdiagnostics-show-category=id -fdiagnostics-parseable-fixits -Wno-trigraphs -fpascal-strings -Wmissing-prototypes -Wreturn-type -Wparentheses -Wswitch -Wno-unused-parameter -Wunused-variable -Wunused-value -Wno-shorten-64-to-32 -isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk -gdwarf-2 -fvisibility=hidden -Wno-sign-conversion -mthumb "-DIBOutlet=__attribute__((iboutlet))" "-DIBOutletCollection(ClassName)=__attribute__((iboutletcollection(ClassName)))" "-DIBAction=void)__attribute__((ibaction)" -miphoneos-version-min=4.3 -MMD -MT dependencies -isysroot $IPHONESDK') + env['CCFLAGS'] = string.split('-fno-objc-arc -arch armv7 -fmessage-length=0 -fno-strict-aliasing -fdiagnostics-print-source-range-info -fdiagnostics-show-category=id -fdiagnostics-parseable-fixits -Wno-trigraphs -fpascal-strings -Wmissing-prototypes -Wreturn-type -Wparentheses -Wswitch -Wno-unused-parameter -Wunused-variable -Wunused-value -Wno-shorten-64-to-32 -isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk -gdwarf-2 -fvisibility=hidden -Wno-sign-conversion -mthumb "-DIBOutlet=__attribute__((iboutlet))" "-DIBOutletCollection(ClassName)=__attribute__((iboutletcollection(ClassName)))" "-DIBAction=void)__attribute__((ibaction)" -miphoneos-version-min=5.1.1 -MMD -MT dependencies -isysroot $IPHONESDK') if (env["bits"]=="64"): env.Append(LINKFLAGS=['-arch', 'arm64', '-Wl,-dead_strip', '-miphoneos-version-min=5.1.1', @@ -80,7 +84,7 @@ def configure(env): '-framework', 'CoreMedia', ]) else: - env.Append(LINKFLAGS=['-arch', 'armv7', '-Wl,-dead_strip', '-miphoneos-version-min=4.3', + env.Append(LINKFLAGS=['-arch', 'armv7', '-Wl,-dead_strip', '-miphoneos-version-min=5.1.1', '-isysroot', '$IPHONESDK', '-framework', 'Foundation', '-framework', 'UIKit', @@ -104,6 +108,9 @@ def configure(env): if env['store_kit'] == 'yes': env.Append(CPPFLAGS=['-DSTOREKIT_ENABLED']) env.Append(LINKFLAGS=['-framework', 'StoreKit']) + + if env['icloud'] == 'yes': + env.Append(CPPFLAGS=['-DICLOUD_ENABLED']) env.Append(CPPPATH = ['$IPHONESDK/usr/include', '$IPHONESDK/System/Library/Frameworks/OpenGLES.framework/Headers', '$IPHONESDK/System/Library/Frameworks/AudioUnit.framework/Headers']) @@ -130,6 +137,14 @@ def configure(env): env['ENV']['CODESIGN_ALLOCATE'] = '/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/codesign_allocate' env.Append(CPPFLAGS=['-DIPHONE_ENABLED', '-DUNIX_ENABLED', '-DGLES2_ENABLED', '-DMPC_FIXED_POINT']) + + if(env["opus"]=="yes"): + env.opus_fixed_point="yes" + if(env["bits"]=="64"): + env.Append(CFLAGS=["-DOPUS_ARM64_OPT"]) + else: + env.Append(CFLAGS=["-DOPUS_ARM_OPT"]) + if env['ios_exceptions'] == 'yes': env.Append(CPPFLAGS=['-fexceptions']) else: diff --git a/platform/iphone/gl_view.h b/platform/iphone/gl_view.h index c58c863510..cda75394db 100755 --- a/platform/iphone/gl_view.h +++ b/platform/iphone/gl_view.h @@ -34,7 +34,7 @@ #import <MediaPlayer/MediaPlayer.h> #import <AVFoundation/AVFoundation.h> -#define USE_CADISPLAYLINK 1 //iOS version 3.1+ is required +#define USE_CADISPLAYLINK 0 //iOS version 3.1+ is required @protocol GLViewDelegate; diff --git a/platform/iphone/gl_view.mm b/platform/iphone/gl_view.mm index 3309fd0820..4d5d1b81e3 100755 --- a/platform/iphone/gl_view.mm +++ b/platform/iphone/gl_view.mm @@ -345,6 +345,8 @@ static void clear_touches() { [self destroyFramebuffer]; [self createFramebuffer]; [self drawView]; + [self drawView]; + } - (BOOL)createFramebuffer diff --git a/platform/iphone/icloud.h b/platform/iphone/icloud.h new file mode 100644 index 0000000000..ca21f62ba1 --- /dev/null +++ b/platform/iphone/icloud.h @@ -0,0 +1,66 @@ +/*************************************************************************/ +/* icloud.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ +#ifdef ICLOUD_ENABLED + +#ifndef ICLOUD_H +#define ICLOUD_H + +#include "core/object.h" + + +class ICloud : public Object { + + OBJ_TYPE(ICloud, Object); + + static ICloud* instance; + static void _bind_methods(); + + List<Variant> pending_events; + +public: + + Error remove_key(Variant p_param); + Variant set_key_values(Variant p_param); + Variant get_key_value(Variant p_param); + Error synchronize_key_values(); + Variant get_all_key_values(); + + int get_pending_event_count(); + Variant pop_pending_event(); + + static ICloud* get_singleton(); + + ICloud(); + ~ICloud(); +}; + + +#endif + +#endif diff --git a/platform/iphone/icloud.mm b/platform/iphone/icloud.mm new file mode 100644 index 0000000000..2dc2f7d9c1 --- /dev/null +++ b/platform/iphone/icloud.mm @@ -0,0 +1,379 @@ +/*************************************************************************/ +/* icloud.mm */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ +#ifdef ICLOUD_ENABLED + +#include "icloud.h" + +extern "C" { +#import <Foundation/Foundation.h> +#import "app_delegate.h" +}; + +ICloud* ICloud::instance = NULL; + +void ICloud::_bind_methods() { + ObjectTypeDB::bind_method(_MD("remove_key"),&ICloud::remove_key); + ObjectTypeDB::bind_method(_MD("set_key_values"),&ICloud::set_key_values); + ObjectTypeDB::bind_method(_MD("get_key_value"),&ICloud::get_key_value); + ObjectTypeDB::bind_method(_MD("synchronize_key_values"),&ICloud::synchronize_key_values); + ObjectTypeDB::bind_method(_MD("get_all_key_values"),&ICloud::get_all_key_values); + + ObjectTypeDB::bind_method(_MD("get_pending_event_count"),&ICloud::get_pending_event_count); + ObjectTypeDB::bind_method(_MD("pop_pending_event"),&ICloud::pop_pending_event); +}; + +int ICloud::get_pending_event_count() { + + return pending_events.size(); +}; + +Variant ICloud::pop_pending_event() { + + Variant front = pending_events.front()->get(); + pending_events.pop_front(); + + return front; +}; + +ICloud* ICloud::get_singleton() { + return instance; +}; + +//convert from apple's abstract type to godot's abstract type.... +Variant nsobject_to_variant(NSObject* object) { + if ([object isKindOfClass:[NSString class]]) { + const char* str = [(NSString*)object UTF8String]; + return String::utf8(str != NULL ? str : ""); + } + else if ([object isKindOfClass:[NSData class]]) { + ByteArray ret; + NSData* data = (NSData*)object; + if ([data length] > 0) { + ret.resize([data length]); + { + ByteArray::Write w = ret.write(); + copymem(w.ptr(), [data bytes], [data length]); + } + } + return ret; + } + else if ([object isKindOfClass:[NSArray class]]) { + Array result; + NSArray* array = (NSArray*)object; + for (unsigned int i = 0; i < [array count]; ++i) { + NSObject* value = [array objectAtIndex:i]; + result.push_back(nsobject_to_variant(value)); + } + return result; + } + else if ([object isKindOfClass:[NSDictionary class]]) { + Dictionary result; + NSDictionary* dic = (NSDictionary*)object; + + + NSArray* keys = [dic allKeys]; + int count = [keys count]; + for (int i=0; i < count; ++i) { + NSObject* k = [ keys objectAtIndex:i]; + NSObject* v = [dic objectForKey:k]; + + result[nsobject_to_variant(k)] = nsobject_to_variant(v); + } + return result; + } + else if ([object isKindOfClass:[NSNumber class]]) { + //Every type except numbers can reliably identify its type. The following is comparing to the *internal* representation, which isn't guaranteed to match the type that was used to create it, and is not advised, particularly when dealing with potential platform differences (ie, 32/64 bit) + //To avoid errors, we'll cast as broadly as possible, and only return int or float. + //bool, char, int, uint, longlong -> int + //float, double -> float + NSNumber* num = (NSNumber*)object; + if(strcmp([num objCType], @encode(BOOL)) == 0) { + return Variant((int)[num boolValue]); + } + else if(strcmp([num objCType], @encode(char)) == 0) { + return Variant((int)[num charValue]); + } + else if(strcmp([num objCType], @encode(int)) == 0) { + return Variant([num intValue]); + } + else if(strcmp([num objCType], @encode(unsigned int)) == 0) { + return Variant((int)[num unsignedIntValue]); + } + else if(strcmp([num objCType], @encode(long long)) == 0) { + return Variant((int)[num longValue]); + } + else if(strcmp([num objCType], @encode(float)) == 0) { + return Variant([num floatValue]); + } + else if(strcmp([num objCType], @encode(double)) == 0) { + return Variant((float)[num doubleValue]); + } + } + else if ([object isKindOfClass:[NSDate class]]) { + //this is a type that icloud supports...but how did you submit it in the first place? + //I guess this is a type that *might* show up, if you were, say, trying to make your game + //compatible with existing cloud data written by another engine's version of your game + WARN_PRINT("NSDate unsupported, returning null Variant") + return Variant(); + } + else if ([object isKindOfClass:[NSNull class]] or object == nil) { + return Variant(); + } + else { + WARN_PRINT("Trying to convert unknown NSObject type to Variant"); + return Variant(); + } +} + +NSObject* variant_to_nsobject(Variant v) { + if (v.get_type() == Variant::STRING) { + return [[[NSString alloc] initWithUTF8String:((String)v).utf8().get_data()] autorelease]; + } + else if (v.get_type() == Variant::REAL) { + return [NSNumber numberWithDouble:(double)v]; + } + else if (v.get_type() == Variant::INT) { + return [NSNumber numberWithLongLong:(long)(int)v]; + } + else if (v.get_type() == Variant::BOOL) { + return [NSNumber numberWithBool:BOOL((bool)v)]; + } + else if (v.get_type() == Variant::DICTIONARY) { + NSMutableDictionary* result = [[[NSMutableDictionary alloc] init] autorelease]; + Dictionary dic = v; + Array keys = dic.keys(); + for (unsigned int i = 0; i < keys.size(); ++i) { + NSString* key = [[[NSString alloc] initWithUTF8String:((String)(keys[i])).utf8().get_data()] autorelease]; + NSObject* value = variant_to_nsobject(dic[keys[i]]); + + if (key == NULL || value == NULL) { + return NULL; + } + + [result setObject:value forKey:key]; + } + return result; + } + else if (v.get_type() == Variant::ARRAY) { + NSMutableArray* result = [[[NSMutableArray alloc] init] autorelease]; + Array arr = v; + for (unsigned int i = 0; i < arr.size(); ++i) { + NSObject* value = variant_to_nsobject(arr[i]); + if (value == NULL) { + //trying to add something unsupported to the array. cancel the whole array + return NULL; + } + [result addObject:value]; + } + return result; + } + else if (v.get_type() == Variant::RAW_ARRAY) { + ByteArray arr = v; + ByteArray::Read r = arr.read(); + NSData* result = [NSData dataWithBytes:r.ptr() length:arr.size()]; + return result; + } + WARN_PRINT(String("Could not add unsupported type to iCloud: '" + Variant::get_type_name(v.get_type())+"'").utf8().get_data()); + return NULL; +} + + +Error ICloud::remove_key(Variant p_param) { + String param = p_param; + NSString* key = [[[NSString alloc] initWithUTF8String:param.utf8().get_data()] autorelease]; + + NSUbiquitousKeyValueStore *store = [NSUbiquitousKeyValueStore defaultStore]; + + if (![[store dictionaryRepresentation] objectForKey:key]) { + return ERR_INVALID_PARAMETER; + } + + [store removeObjectForKey:key]; + return OK; +} + +//return an array of the keys that could not be set +Variant ICloud::set_key_values(Variant p_params) { + Dictionary params = p_params; + Array keys = params.keys(); + + Array error_keys; + + for (unsigned int i = 0; i < keys.size(); ++i) { + String variant_key = keys[i]; + Variant variant_value = params[variant_key]; + + NSString* key = [[[NSString alloc] initWithUTF8String:variant_key.utf8().get_data()] autorelease]; + if (key == NULL) { + error_keys.push_back(variant_key); + continue; + } + + NSObject* value = variant_to_nsobject(variant_value); + + if (value == NULL) { + error_keys.push_back(variant_key); + continue; + } + + NSUbiquitousKeyValueStore *store = [NSUbiquitousKeyValueStore defaultStore]; + [store setObject:value forKey:key]; + } + + return error_keys; +} + +Variant ICloud::get_key_value(Variant p_param) { + String param = p_param; + + NSString* key = [[[NSString alloc] initWithUTF8String:param.utf8().get_data()] autorelease]; + NSUbiquitousKeyValueStore *store = [NSUbiquitousKeyValueStore defaultStore]; + + if (![[store dictionaryRepresentation] objectForKey:key]) { + return Variant(); + } + + Variant result = nsobject_to_variant([[store dictionaryRepresentation] objectForKey:key]); + + return result; +} + +Variant ICloud::get_all_key_values() { + Dictionary result; + + NSUbiquitousKeyValueStore* store = [NSUbiquitousKeyValueStore defaultStore]; + NSDictionary* store_dictionary = [store dictionaryRepresentation]; + + NSArray* keys = [store_dictionary allKeys]; + int count = [keys count]; + for (int i=0; i < count; ++i) { + NSString* k = [ keys objectAtIndex:i]; + NSObject* v = [store_dictionary objectForKey:k]; + + const char* str = [k UTF8String]; + if (str != NULL) { + result[String::utf8(str)] = nsobject_to_variant(v); + } + } + + return result; +} + +Error ICloud::synchronize_key_values() { + NSUbiquitousKeyValueStore *store = [NSUbiquitousKeyValueStore defaultStore]; + BOOL result = [store synchronize]; + if (result == YES) { + return OK; + } + else { + return FAILED; + } +} +/* +Error ICloud::initial_sync() { + //you sometimes have to write something to the store to get it to download new data. go apple! + NSUbiquitousKeyValueStore *store = [NSUbiquitousKeyValueStore defaultStore]; + if ([store boolForKey:@"isb"]) + { + [store setBool:NO forKey:@"isb"]; + } + else + { + [store setBool:YES forKey:@"isb"]; + } + return synchronize(); +} +*/ +ICloud::ICloud() { + ERR_FAIL_COND(instance != NULL); + instance = this; + //connected = false; + + [ + //[NSNotificationCenter defaultCenter] addObserverForName: @"notify" + [NSNotificationCenter defaultCenter] addObserverForName: NSUbiquitousKeyValueStoreDidChangeExternallyNotification + object: [NSUbiquitousKeyValueStore defaultStore] + queue: nil + usingBlock: ^ (NSNotification * notification) { + NSDictionary* userInfo = [notification userInfo]; + NSInteger change = [[userInfo objectForKey:NSUbiquitousKeyValueStoreChangeReasonKey] integerValue]; + + Dictionary ret; + ret["type"] = "key_value_changed"; + + //StringArray result_keys; + //Array result_values; + Dictionary keyValues; + String reason = ""; + + if (change == NSUbiquitousKeyValueStoreServerChange) { + reason = "server"; + } + else if (change == NSUbiquitousKeyValueStoreInitialSyncChange) { + reason = "initial_sync"; + } + else if (change == NSUbiquitousKeyValueStoreQuotaViolationChange) { + reason = "quota_violation"; + } + else if (change == NSUbiquitousKeyValueStoreAccountChange) { + reason = "account"; + } + + ret["reason"] = reason; + + + NSUbiquitousKeyValueStore *store = [NSUbiquitousKeyValueStore defaultStore]; + + NSArray * keys = [userInfo objectForKey:NSUbiquitousKeyValueStoreChangedKeysKey]; + for (NSString* key in keys) { + const char* str = [key UTF8String]; + if (str == NULL) { + continue; + } + + NSObject* object = [store objectForKey:key]; + + //figure out what kind of object it is + Variant value = nsobject_to_variant(object); + + keyValues[String::utf8(str)] = value; + } + + ret["changed_values"] = keyValues; + pending_events.push_back(ret); + } + ]; +} + + +ICloud::~ICloud() { + +}; + +#endif diff --git a/platform/iphone/in_app_store.mm b/platform/iphone/in_app_store.mm index e3ba6bbd73..f689123c81 100644 --- a/platform/iphone/in_app_store.mm +++ b/platform/iphone/in_app_store.mm @@ -28,6 +28,10 @@ /*************************************************************************/ #ifdef STOREKIT_ENABLED +#ifdef MODULE_FUSEBOXX_ENABLED +#import "modules/fuseboxx/ios/FuseSDK.h" +#endif + #include "in_app_store.h" extern "C" { @@ -222,6 +226,11 @@ Error InAppStore::request_product_info(Variant p_params) { else{ [pending_transactions setObject:transaction forKey:transaction.payment.productIdentifier]; } + + #ifdef MODULE_FUSEBOXX_ENABLED + printf("Registering transaction on Fuseboxx!\n"); + [FuseSDK registerInAppPurchase: transaction]; + #endif } break; case SKPaymentTransactionStateFailed: { printf("status transaction failed!\n"); diff --git a/platform/iphone/os_iphone.cpp b/platform/iphone/os_iphone.cpp index ade1c292a4..93f4d00e05 100644 --- a/platform/iphone/os_iphone.cpp +++ b/platform/iphone/os_iphone.cpp @@ -160,6 +160,12 @@ void OSIPhone::initialize(const VideoMode& p_desired,int p_video_driver,int p_au store_kit = memnew(InAppStore); Globals::get_singleton()->add_singleton(Globals::Singleton("InAppStore", store_kit)); #endif + +#ifdef ICLOUD_ENABLED + icloud = memnew(ICloud); + Globals::get_singleton()->add_singleton(Globals::Singleton("ICloud", icloud)); + //icloud->connect(); +#endif }; MainLoop *OSIPhone::get_main_loop() const { diff --git a/platform/iphone/os_iphone.h b/platform/iphone/os_iphone.h index 844f067552..06a67b0cfd 100644 --- a/platform/iphone/os_iphone.h +++ b/platform/iphone/os_iphone.h @@ -43,8 +43,11 @@ #include "servers/audio/sample_manager_sw.h" #include "servers/spatial_sound/spatial_sound_server_sw.h" #include "servers/spatial_sound_2d/spatial_sound_2d_server_sw.h" +#include "main/input_default.h" #include "game_center.h" #include "in_app_store.h" +#include "icloud.h" + class AudioDriverIphone; class RasterizerGLES2; @@ -88,6 +91,9 @@ private: #ifdef STOREKIT_ENABLED InAppStore* store_kit; #endif +#ifdef ICLOUD_ENABLED + ICloud* icloud; +#endif MainLoop *main_loop; diff --git a/platform/iphone/view_controller.mm b/platform/iphone/view_controller.mm index bc9950979e..6a9c3ac9ec 100644 --- a/platform/iphone/view_controller.mm +++ b/platform/iphone/view_controller.mm @@ -129,10 +129,12 @@ int add_cmdline(int p_argc, char** p_args) { return YES; } +#ifdef GAME_CENTER_ENABLED - (void) gameCenterViewControllerDidFinish:(GKGameCenterViewController*) gameCenterViewController { //[gameCenterViewController dismissViewControllerAnimated:YES completion:^{GameCenter::get_singleton()->game_center_closed();}];//version for signaling when overlay is completely gone GameCenter::get_singleton()->game_center_closed(); [gameCenterViewController dismissViewControllerAnimated:YES completion:nil]; } +#endif @end |