Skip to content

Instantly share code, notes, and snippets.

@AllieCarver
Last active February 14, 2017 02:50
Show Gist options
  • Save AllieCarver/7c1bce67e9e1b723fa4866c37b61b56a to your computer and use it in GitHub Desktop.
Save AllieCarver/7c1bce67e9e1b723fa4866c37b61b56a to your computer and use it in GitHub Desktop.
//
// 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);
}
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