Last active
February 14, 2017 02:50
-
-
Save AllieCarver/7c1bce67e9e1b723fa4866c37b61b56a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// main.m | |
// nienie | |
/* | |
credit to Gabriele Greco from | |
https://forums.libsdl.org/viewtopic.php?t=8906&sid=b72546db8669ba672be8253304974314 | |
This is slightly modifified version of his ad banner class from his project | |
source | |
https://sourceforge.net/p/etw/code/HEAD/tree/trunk/etw/Banner.m#l4 | |
*/ | |
#import <Foundation/Foundation.h> | |
#import <UIKit/UIKit.h> | |
#include ".../kivy-ios/dist/root/python/include/python2.7/Python.h" | |
#include ".../kivy-ios/dist/include/common/sdl2/SDL_main.h" | |
#include <dlfcn.h> | |
@import GoogleMobileAds; | |
void export_orientation(); | |
void load_custom_builtin_importer(); | |
UIView *gView; | |
UIViewController *gViewColtroller; | |
@interface myBanner : NSObject <GADBannerViewDelegate> | |
@property (nonatomic) BOOL show_ads; | |
@property (strong, nonatomic) GADBannerView *gbanner; | |
@property (strong, nonatomic) GADRequest *request; | |
@end | |
static myBanner *vbanner = nil; | |
@implementation myBanner | |
-(id)init { | |
// admob allocation | |
NSLog(@"Creating google banner object"); | |
self.request = [GADRequest request]; | |
// I'm not sure this is even necessary | |
self.request.testDevices = @[@"Simulator"]; | |
//SDLUIKitDelegate *sdldelegate = [SDLUIKitDelegate sharedAppDelegate]; | |
UIWindow *window = [UIApplication sharedApplication].keyWindow; | |
UIViewController *rootViewController = window.rootViewController; | |
gViewColtroller = rootViewController;//[[SDLLaunchScreenController alloc] init]; | |
gView = rootViewController.view; ///gViewColtroller.view; | |
// Create a view of the standard size at the top of the screen. | |
// Available AdSize constants are explained in GADAdSize.h. | |
self.gbanner = [[GADBannerView alloc] initWithAdSize:kGADAdSizeBanner]; | |
[self.gbanner setDelegate:self]; | |
// Specify the ad's "unit identifier." This is your AdMob Publisher ID. | |
//left this in might use later add unit id is test id from google docs | |
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) | |
self.gbanner.adUnitID = @"ca-app-pub-3940256099942544/2934735716"; | |
else | |
self.gbanner.adUnitID = @"ca-app-pub-3940256099942544/2934735716"; | |
self.gbanner.hidden = TRUE; | |
// Let the runtime know which UIViewController to restore after taking | |
// the user wherever the ad goes and add it to the view hierarchy. | |
self.gbanner.rootViewController = gViewColtroller; | |
[gView addSubview:self.gbanner]; | |
[self.gbanner loadRequest:self.request]; | |
self.show_ads = TRUE; | |
return self; | |
} | |
// Called before ad is shown, good time to show the add | |
- (void)adViewDidReceiveAd:(GADBannerView *)view | |
{ | |
NSLog(@"Admob load"); | |
self.gbanner.hidden = !self.show_ads; | |
} | |
// An error occured | |
- (void)adView:(GADBannerView *)view didFailToReceiveAdWithError:(GADRequestError *)error | |
{ | |
NSLog(@"Admob error: %@", error); | |
self.gbanner.hidden = TRUE; | |
} | |
-(void)dealloc { | |
NSLog(@"Freeing ads"); | |
if (self.gbanner) { | |
[self.gbanner removeFromSuperview]; | |
[self.gbanner release]; | |
self.gbanner.delegate = nil; | |
self.gbanner = nil; | |
} | |
[super dealloc]; | |
} | |
- (void)showAds:(int)ontop { | |
self.show_ads = TRUE; | |
NSLog(@"Displaying banner object ontop:%d.", ontop); | |
CGSize AdSize = kGADAdSizeBanner.size; | |
CGRect frame = self.gbanner.frame; | |
frame.origin.x = (gViewColtroller.view.bounds.size.width - AdSize.width) / 2 ; | |
if (ontop) | |
frame.origin.y = 0.0f; | |
else | |
frame.origin.y = gViewColtroller.view.bounds.size.height - AdSize.height; | |
self.gbanner.frame = frame; | |
} | |
@end | |
@interface adSwitch : NSObject | |
@end | |
@implementation adSwitch | |
-(id)init { | |
if (!vbanner) | |
{ | |
vbanner = [[myBanner alloc] init]; | |
[vbanner showAds:0]; | |
} | |
return self; | |
} | |
-(void) show_ads { | |
if (!vbanner) | |
vbanner = [[myBanner alloc] init]; | |
[vbanner showAds:0]; | |
} | |
-(void) hide_ads { | |
if (vbanner) | |
{ | |
[vbanner release]; | |
vbanner = nil; | |
} | |
} | |
@end | |
int main(int argc, char *argv[]) { | |
int ret = 0; | |
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; | |
// Change the executing path to YourApp | |
chdir("YourApp"); | |
// Special environment to prefer .pyo, and don't write bytecode if .py are found | |
// because the process will not have a write attribute on the device. | |
putenv("PYTHONOPTIMIZE=2"); | |
putenv("PYTHONDONTWRITEBYTECODE=1"); | |
putenv("PYTHONNOUSERSITE=1"); | |
putenv("PYTHONPATH=."); | |
//putenv("PYTHONVERBOSE=1"); | |
// Kivy environment to prefer some implementation on iOS platform | |
putenv("KIVY_BUILD=ios"); | |
putenv("KIVY_NO_CONFIG=1"); | |
putenv("KIVY_NO_FILELOG=1"); | |
//putenv("PYOBJUS_DEBUG=1"); | |
putenv("KIVY_WINDOW=sdl2"); | |
putenv("KIVY_IMAGE=imageio,tex"); | |
putenv("KIVY_AUDIO=sdl2"); | |
#ifndef DEBUG | |
putenv("KIVY_NO_CONSOLELOG=1"); | |
#endif | |
// Export orientation preferences for Kivy | |
export_orientation(); | |
NSString * resourcePath = [[NSBundle mainBundle] resourcePath]; | |
NSLog(@"PythonHome is: %s", (char *)[resourcePath UTF8String]); | |
Py_SetPythonHome((char *)[resourcePath UTF8String]); | |
NSLog(@"Initializing python"); | |
Py_Initialize(); | |
PySys_SetArgv(argc, argv); | |
// If other modules are using the thread, we need to initialize them before. | |
PyEval_InitThreads(); | |
// Add an importer for builtin modules | |
load_custom_builtin_importer(); | |
// Search and start main.py | |
const char * prog = [ | |
[[NSBundle mainBundle] pathForResource:@"YourApp/main" ofType:@"pyo"] cStringUsingEncoding: | |
NSUTF8StringEncoding]; | |
//instantiate the google? is there better place? | |
[GADMobileAds configureWithApplicationID:@"YOUR_APP_ID_HERE"]; | |
NSLog(@"Running main.pyo: %s", prog); | |
FILE* fd = fopen(prog, "r"); | |
if ( fd == NULL ) { | |
ret = 1; | |
NSLog(@"Unable to open main.pyo, abort."); | |
} else { | |
ret = PyRun_SimpleFileEx(fd, prog, 1); | |
if (ret != 0) | |
NSLog(@"Application quit abnormally!"); | |
} | |
Py_Finalize(); | |
NSLog(@"Leaving"); | |
[pool release]; | |
// Look like the app still runs even when we left here. | |
exit(ret); | |
return ret; | |
} | |
// This method reads the available orientations from the Info.plist file and | |
// shares them via an environment variable. Kivy will automatically set the | |
// orientation according to this environment value, if it exists. To restrict | |
// the allowed orientation, please see the comments inside. | |
void export_orientation() { | |
NSDictionary *info = [[NSBundle mainBundle] infoDictionary]; | |
NSArray *orientations = [info objectForKey:@"UISupportedInterfaceOrientations"]; | |
// Orientation restrictions | |
// ======================== | |
// Comment or uncomment blocks 1-3 in order the limit orientation support | |
// 1. Landscape only | |
// NSString *result = [[NSString alloc] initWithString:@"KIVY_ORIENTATION=LandscapeLeft LandscapeRight"]; | |
// 2. Portrait only | |
// NSString *result = [[NSString alloc] initWithString:@"KIVY_ORIENTATION=Portrait PortraitUpsideDown"]; | |
// 3. All orientations | |
NSString *result = [[NSString alloc] initWithString:@"KIVY_ORIENTATION="]; | |
for (int i = 0; i < [orientations count]; i++) { | |
NSString *item = [orientations objectAtIndex:i]; | |
item = [item substringFromIndex:22]; | |
if (i > 0) | |
result = [result stringByAppendingString:@" "]; | |
result = [result stringByAppendingString:item]; | |
} | |
// ======================== | |
putenv((char *)[result UTF8String]); | |
NSLog(@"Available orientation: %@", result); | |
} | |
void load_custom_builtin_importer() { | |
static const char *custom_builtin_importer = \ | |
"import sys, imp\n" \ | |
"from os import environ\n" \ | |
"from os.path import exists, join\n" \ | |
"# Fake redirection to supress console output\n" \ | |
"if environ.get('KIVY_NO_CONSOLE', '0') == '1':\n" \ | |
" class fakestd(object):\n" \ | |
" def write(self, *args, **kw): pass\n" \ | |
" def flush(self, *args, **kw): pass\n" \ | |
" sys.stdout = fakestd()\n" \ | |
" sys.stderr = fakestd()\n" \ | |
"# Custom builtin importer for precompiled modules\n" \ | |
"class CustomBuiltinImporter(object):\n" \ | |
" def find_module(self, fullname, mpath=None):\n" \ | |
" if '.' not in fullname:\n" \ | |
" return\n" \ | |
" if not mpath:\n" \ | |
" return\n" \ | |
" part = fullname.rsplit('.')[-1]\n" \ | |
" fn = join(mpath[0], '{}.so'.format(part))\n" \ | |
" if exists(fn):\n" \ | |
" return self\n" \ | |
" return\n" \ | |
" def load_module(self, fullname):\n" \ | |
" f = fullname.replace('.', '_')\n" \ | |
" mod = sys.modules.get(f)\n" \ | |
" if mod is None:\n" \ | |
" #print 'LOAD DYNAMIC', f, sys.modules.keys()\n" \ | |
" try:\n" \ | |
" mod = imp.load_dynamic(f, f)\n" \ | |
" except ImportError:\n" \ | |
" #print 'LOAD DYNAMIC FALLBACK', fullname\n" \ | |
" mod = imp.load_dynamic(fullname, fullname)\n" \ | |
" return mod\n" \ | |
" return mod\n" \ | |
"sys.meta_path.append(CustomBuiltinImporter())"; | |
PyRun_SimpleString(custom_builtin_importer); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from pyobjus import autoclass | |
adswitch = autoclass('adSwitch').alloc().init() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment