# HG changeset patch # User koda # Date 1292028916 -3600 # Node ID 8906b2409d9752eda06b06713d3bfde7b42907e4 # Parent a8ab151bcae31dab4cfe2d4e12409694f0e5f6e6 add the appirater class for getting more positive reviews enabled full multitasking for iphone (but only with ios >= 4.2) fixed a glitch that would leave stuff onscreen while ammo menu open diff -r a8ab151bcae3 -r 8906b2409d97 project_files/HedgewarsMobile/Classes/Appirater.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project_files/HedgewarsMobile/Classes/Appirater.h Sat Dec 11 01:55:16 2010 +0100 @@ -0,0 +1,105 @@ +/* + This file is part of Appirater. + + Copyright (c) 2010, Arash Payan + All rights reserved. + + 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. + */ +/* + * Appirater.h + * appirater + * + * Created by Arash Payan on 9/5/09. + * http://arashpayan.com + * Copyright 2010 Arash Payan. All rights reserved. + */ + +#import + +extern NSString *const kAppiraterLaunchDate; +extern NSString *const kAppiraterLaunchCount; +extern NSString *const kAppiraterCurrentVersion; +extern NSString *const kAppiraterRatedCurrentVersion; +extern NSString *const kAppiraterDeclinedToRate; + +/* + Place your Apple generated software id here. + */ +#define APPIRATER_APP_ID 391234866 + +/* + Your app's name. + */ +#define APPIRATER_APP_NAME [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey] + +/* + This is the message your users will see once they've passed the day+launches + threshold. + */ +#define APPIRATER_MESSAGE [NSString stringWithFormat:@"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!", APPIRATER_APP_NAME] + +/* + This is the title of the message alert that users will see. + */ +#define APPIRATER_MESSAGE_TITLE [NSString stringWithFormat:@"Rate %@", APPIRATER_APP_NAME] + +/* + The text of the button that rejects reviewing the app. + */ +#define APPIRATER_CANCEL_BUTTON NSLocalizedString(@"No thanks",@"") + +/* + Text of button that will send user to app review page. + */ +#define APPIRATER_RATE_BUTTON [NSString stringWithFormat:@"Rate %@", APPIRATER_APP_NAME] + +/* + Text for button to remind the user to review later. + */ +#define APPIRATER_RATE_LATER NSLocalizedString(@"Remind me later",@"") + +/* + Users will need to have the same version of your app installed for this many + days before they will be prompted to rate it. + */ +#define DAYS_UNTIL_PROMPT 5 // double + +/* + Users will need to launch the same version of the app this many times before + they will be prompted to rate it. + */ +#define LAUNCHES_UNTIL_PROMPT 10 // integer + +/* + 'YES' will show the Appirater alert everytime. Useful for testing how your message + looks and making sure the link to your app's review page works. + */ +#define APPIRATER_DEBUG NO // bool + +@interface Appirater : NSObject { + +} + ++(void) appLaunched; + +@end diff -r a8ab151bcae3 -r 8906b2409d97 project_files/HedgewarsMobile/Classes/Appirater.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project_files/HedgewarsMobile/Classes/Appirater.m Sat Dec 11 01:55:16 2010 +0100 @@ -0,0 +1,207 @@ +/* + This file is part of Appirater. + + Copyright (c) 2010, Arash Payan + All rights reserved. + + 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. + */ +/* + * Appirater.m + * appirater + * + * Created by Arash Payan on 9/5/09. + * http://arashpayan.com + * Copyright 2010 Arash Payan. All rights reserved. + */ + +#import "Appirater.h" +#import +#import + +NSString *const kAppiraterLaunchDate = @"kAppiraterLaunchDate"; +NSString *const kAppiraterLaunchCount = @"kAppiraterLaunchCount"; +NSString *const kAppiraterCurrentVersion = @"kAppiraterCurrentVersion"; +NSString *const kAppiraterRatedCurrentVersion = @"kAppiraterRatedCurrentVersion"; +NSString *const kAppiraterDeclinedToRate = @"kAppiraterDeclinedToRate"; + +NSString *templateReviewURL = @"itms-apps://itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?id=APP_ID&onlyLatestVersion=true&pageNumber=0&sortOrdering=1&type=Purple+Software"; + +@interface Appirater (hidden) + +-(BOOL) connectedToNetwork; + +@end + +@implementation Appirater (hidden) + +-(BOOL) connectedToNetwork { + // Create zero addy + struct sockaddr_in zeroAddress; + bzero(&zeroAddress, sizeof(zeroAddress)); + zeroAddress.sin_len = sizeof(zeroAddress); + zeroAddress.sin_family = AF_INET; + + // Recover reachability flags + SCNetworkReachabilityRef defaultRouteReachability = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&zeroAddress); + SCNetworkReachabilityFlags flags; + + BOOL didRetrieveFlags = SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags); + CFRelease(defaultRouteReachability); + + if (!didRetrieveFlags) { + NSLog(@"Error. Could not recover network reachability flags"); + return NO; + } + + BOOL isReachable = flags & kSCNetworkFlagsReachable; + BOOL needsConnection = flags & kSCNetworkFlagsConnectionRequired; + BOOL nonWiFi = flags & kSCNetworkReachabilityFlagsTransientConnection; + + NSURL *testURL = [NSURL URLWithString:@"http://www.apple.com/"]; + NSURLRequest *testRequest = [NSURLRequest requestWithURL:testURL cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:20.0]; + NSURLConnection *testConnection = [[NSURLConnection alloc] initWithRequest:testRequest delegate:self]; + + return ((isReachable && !needsConnection) || nonWiFi) ? (testConnection ? YES : NO) : NO; +} + +@end + + +@implementation Appirater + ++(void) appLaunched { + Appirater *appirater = [[Appirater alloc] init]; + [NSThread detachNewThreadSelector:@selector(appLaunchedHandler) toTarget:appirater withObject:nil]; +} + +-(void) appLaunchedHandler { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + + if (APPIRATER_DEBUG) { + [self performSelectorOnMainThread:@selector(showPrompt) withObject:nil waitUntilDone:NO]; + return; + } + + BOOL willShowPrompt = NO; + + // get the app's version + NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleVersionKey]; + + // get the version number that we've been tracking + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + NSString *trackingVersion = [userDefaults stringForKey:kAppiraterCurrentVersion]; + if (trackingVersion == nil) { + trackingVersion = version; + [userDefaults setObject:version forKey:kAppiraterCurrentVersion]; + } + + if (APPIRATER_DEBUG) + DLog(@"APPIRATER Tracking version: %@", trackingVersion); + + if ([trackingVersion isEqualToString:version]) { + // get the launch date + NSTimeInterval timeInterval = [userDefaults doubleForKey:kAppiraterLaunchDate]; + if (timeInterval == 0) { + timeInterval = [[NSDate date] timeIntervalSince1970]; + [userDefaults setDouble:timeInterval forKey:kAppiraterLaunchDate]; + } + + NSTimeInterval secondsSinceLaunch = [[NSDate date] timeIntervalSinceDate:[NSDate dateWithTimeIntervalSince1970:timeInterval]]; + double secondsUntilPrompt = 60 * 60 * 24 * DAYS_UNTIL_PROMPT; + + // get the launch count + int launchCount = [userDefaults integerForKey:kAppiraterLaunchCount]; + launchCount++; + [userDefaults setInteger:launchCount forKey:kAppiraterLaunchCount]; + if (APPIRATER_DEBUG) + NSLog(@"APPIRATER Launch count: %d", launchCount); + + // have they previously declined to rate this version of the app? + BOOL declinedToRate = [userDefaults boolForKey:kAppiraterDeclinedToRate]; + + // have they already rated the app? + BOOL ratedApp = [userDefaults boolForKey:kAppiraterRatedCurrentVersion]; + + if (secondsSinceLaunch > secondsUntilPrompt && + launchCount > LAUNCHES_UNTIL_PROMPT && + !declinedToRate && + !ratedApp) { + if ([self connectedToNetwork]) { // check if they can reach the app store + willShowPrompt = YES; + [self performSelectorOnMainThread:@selector(showPrompt) withObject:nil waitUntilDone:NO]; + } + } + } else { + // it's a new version of the app, so restart tracking + [userDefaults setObject:version forKey:kAppiraterCurrentVersion]; + [userDefaults setDouble:[[NSDate date] timeIntervalSince1970] forKey:kAppiraterLaunchDate]; + [userDefaults setInteger:1 forKey:kAppiraterLaunchCount]; + [userDefaults setBool:NO forKey:kAppiraterRatedCurrentVersion]; + [userDefaults setBool:NO forKey:kAppiraterDeclinedToRate]; + } + + [userDefaults synchronize]; + if (!willShowPrompt) + [self autorelease]; + + [pool release]; +} + +-(void) showPrompt { + UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:APPIRATER_MESSAGE_TITLE + message:APPIRATER_MESSAGE + delegate:self + cancelButtonTitle:APPIRATER_CANCEL_BUTTON + otherButtonTitles:APPIRATER_RATE_BUTTON, APPIRATER_RATE_LATER, nil]; + [alertView show]; + [alertView release]; +} + +-(void) alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger) buttonIndex { + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + + switch (buttonIndex) { + case 0: + // they don't want to rate it + [userDefaults setBool:YES forKey:kAppiraterDeclinedToRate]; + break; + case 1: + // they want to rate it + [[UIApplication sharedApplication] openURL: + [NSURL URLWithString:[templateReviewURL stringByReplacingOccurrencesOfString:@"APP_ID" withString:[NSString stringWithFormat:@"%d", APPIRATER_APP_ID]]]]; + + [userDefaults setBool:YES forKey:kAppiraterRatedCurrentVersion]; + break; + case 2: + // remind them later + break; + default: + break; + } + + [userDefaults synchronize]; + + [self release]; +} + +@end diff -r a8ab151bcae3 -r 8906b2409d97 project_files/HedgewarsMobile/Classes/GameConfigViewController.m --- a/project_files/HedgewarsMobile/Classes/GameConfigViewController.m Sat Dec 11 01:00:00 2010 +0100 +++ b/project_files/HedgewarsMobile/Classes/GameConfigViewController.m Sat Dec 11 01:55:16 2010 +0100 @@ -226,9 +226,6 @@ [NSNumber numberWithInt:self.interfaceOrientation],@"orientation", nil]; - // finally launch game and remove this controller - DLog(@"sending config %@", gameDictionary); - NSDictionary *allDataNecessary = [NSDictionary dictionaryWithObjectsAndKeys:gameDictionary,@"game_dictionary", @"",@"savefile", [NSNumber numberWithBool:NO],@"netgame", nil]; if (IS_IPAD()) diff -r a8ab151bcae3 -r 8906b2409d97 project_files/HedgewarsMobile/Classes/ObjcExports.h --- a/project_files/HedgewarsMobile/Classes/ObjcExports.h Sat Dec 11 01:00:00 2010 +0100 +++ b/project_files/HedgewarsMobile/Classes/ObjcExports.h Sat Dec 11 01:55:16 2010 +0100 @@ -31,5 +31,6 @@ BOOL isGameRunning(); void setGameRunning(BOOL value); NSInteger cachedGrenadeTime(); +void clearView(); void setGrenadeTime(NSInteger value); void setAmmoMenuInstance(AmmoMenuViewController *instance); diff -r a8ab151bcae3 -r 8906b2409d97 project_files/HedgewarsMobile/Classes/ObjcExports.m --- a/project_files/HedgewarsMobile/Classes/ObjcExports.m Sat Dec 11 01:00:00 2010 +0100 +++ b/project_files/HedgewarsMobile/Classes/ObjcExports.m Sat Dec 11 01:55:16 2010 +0100 @@ -96,6 +96,7 @@ } void clearView() { + // don't use any engine calls here as this function is called every time the ammomenu is opened UIWindow *theWindow = (IS_DUALHEAD()) ? [SDLUIKitDelegate sharedAppDelegate].uiwindow : [[UIApplication sharedApplication] keyWindow]; UIButton *theButton = (UIButton *)[theWindow viewWithTag:CONFIRMATION_TAG]; UISegmentedControl *theSegment = (UISegmentedControl *)[theWindow viewWithTag:GRENADE_TAG]; @@ -166,6 +167,7 @@ gAudioSessionInited = YES; } UInt32 propertySize = sizeof(CFStringRef); + BOOL muteResult = NO; // this checks if there is volume Float32 volume; @@ -179,9 +181,10 @@ n = AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &propertySize, &state); if (n != 0) DLog( @"AudioSessionGetProperty 'audioRoute': %d", n ); - NSString *result = (NSString *)state; - BOOL muteResult = ([result length] == 0); - releaseAndNil(result); - + else { + NSString *result = (NSString *)state; + muteResult = ([result length] == 0); + releaseAndNil(result); + } return volumeResult || muteResult; } diff -r a8ab151bcae3 -r 8906b2409d97 project_files/HedgewarsMobile/Classes/OverlayViewController.m --- a/project_files/HedgewarsMobile/Classes/OverlayViewController.m Sat Dec 11 01:00:00 2010 +0100 +++ b/project_files/HedgewarsMobile/Classes/OverlayViewController.m Sat Dec 11 01:55:16 2010 +0100 @@ -395,6 +395,7 @@ break; case 10: playSound(@"clickSound"); + clearView(); HW_pause(); if (self.amvc.isVisible && IS_DUALHEAD() == NO) { doDim(); @@ -405,6 +406,7 @@ break; case 11: playSound(@"clickSound"); + clearView(); removeConfirmationInput(); if (IS_DUALHEAD() || self.useClassicMenu == NO) { diff -r a8ab151bcae3 -r 8906b2409d97 project_files/HedgewarsMobile/Classes/SDL_uikitappdelegate.m --- a/project_files/HedgewarsMobile/Classes/SDL_uikitappdelegate.m Sat Dec 11 01:00:00 2010 +0100 +++ b/project_files/HedgewarsMobile/Classes/SDL_uikitappdelegate.m Sat Dec 11 01:55:16 2010 +0100 @@ -24,7 +24,6 @@ #import "SDL_uikitopenglview.h" #import "SDL_uikitwindow.h" #import "SDL_events_c.h" -#import "../SDL_sysvideo.h" #import "jumphack.h" #import "SDL_video.h" #import "SDL_mixer.h" @@ -34,6 +33,8 @@ #import "GameSetup.h" #import "MainMenuViewController.h" #import "OverlayViewController.h" +#import "Appirater.h" +#include #ifdef main #undef main @@ -41,16 +42,15 @@ #define BLACKVIEW_TAG 17935 #define SECONDBLACKVIEW_TAG 48620 -#define VALGRIND "/opt/valgrind/bin/valgrind" +#define VALGRIND "/opt/fink/bin/valgrind" int main (int argc, char *argv[]) { #ifdef VALGRIND_REXEC // Using the valgrind build config, rexec ourself in valgrind // from http://landonf.bikemonkey.org/code/iphone/iPhone_Simulator_Valgrind.20081224.html if (argc < 2 || (argc >= 2 && strcmp(argv[1], "-valgrind") != 0)) - execl(VALGRIND, VALGRIND, "--leak-check=full", argv[0], "-valgrind", NULL); + execl(VALGRIND, VALGRIND, "--leak-check=full", "--dsymutil=yes", argv[0], "-valgrind", NULL); #endif - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; int retVal = UIApplicationMain(argc, argv, nil, @"SDLUIKitDelegate"); [pool release]; @@ -173,7 +173,7 @@ } // override the direct execution of SDL_main to allow us to implement the frontend (or even using a nib) --(void) applicationDidFinishLaunching:(UIApplication *)application { +-(BOOL) application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [application setStatusBarHidden:YES]; self.uiwindow = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; @@ -204,6 +204,9 @@ [titleView release]; [self.secondWindow makeKeyAndVisible]; } + + [Appirater appLaunched]; + return YES; } -(void) applicationWillTerminate:(UIApplication *)application { @@ -227,15 +230,15 @@ if ([device respondsToSelector:@selector(isMultitaskingSupported)] && device.multitaskingSupported && self.isInGame) { - // there is a bug on iphone that presents a sdl view with a black screen, so it returns to frontend - if (IS_IPAD()) + // multiasking in-game works only for ios >= 4.2, returns a black screen on other verions + if (NSClassFromString(@"UIPrintInfo")) HW_suspend(); else { - // while screen is loading you can't call HW_terminate() so we close the app + // so the game returns to the configuration view if (isGameRunning()) HW_terminate(NO); else { - // force app closure + // while screen is loading you can't call HW_terminate() so we close the app SDL_SendQuit(); HW_terminate(YES); longjmp(*(jump_env()), 1); diff -r a8ab151bcae3 -r 8906b2409d97 project_files/HedgewarsMobile/Classes/TeamConfigViewController.m --- a/project_files/HedgewarsMobile/Classes/TeamConfigViewController.m Sat Dec 11 01:00:00 2010 +0100 +++ b/project_files/HedgewarsMobile/Classes/TeamConfigViewController.m Sat Dec 11 01:55:16 2010 +0100 @@ -236,7 +236,7 @@ label.textColor = [UIColor whiteColor]; label.numberOfLines = 1; if (section == 0) - label.text = NSLocalizedString(@"Tap to add hogs or change color, hold tap to remove team.",@""); + label.text = NSLocalizedString(@"Tap to add hogs or change color, touch and hold to remove team.",@""); else label.text = NSLocalizedString(@"The robot badge indicates an AI-controlled team.",@""); diff -r a8ab151bcae3 -r 8906b2409d97 project_files/HedgewarsMobile/Hedgewars.xcodeproj/project.pbxproj --- a/project_files/HedgewarsMobile/Hedgewars.xcodeproj/project.pbxproj Sat Dec 11 01:00:00 2010 +0100 +++ b/project_files/HedgewarsMobile/Hedgewars.xcodeproj/project.pbxproj Sat Dec 11 01:55:16 2010 +0100 @@ -182,6 +182,7 @@ 61A670C012747D9B00B06CE7 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 6183D83D11E2BCE200A88903 /* Default.png */; }; 61A670C112747DB900B06CE7 /* MainMenuViewController-iPhone.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6165924C11CA9CB400D6E256 /* MainMenuViewController-iPhone.xib */; }; 61A670C212747DBD00B06CE7 /* MapConfigViewController-iPhone.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6165924E11CA9CB400D6E256 /* MapConfigViewController-iPhone.xib */; }; + 61AC067412B2E32D000B52A2 /* Appirater.m in Sources */ = {isa = PBXBuildFile; fileRef = 61AC067312B2E32D000B52A2 /* Appirater.m */; }; 61B3D71C11EA6F2700EC7420 /* uKeys.pas in Sources */ = {isa = PBXBuildFile; fileRef = 617987FE114AA34C00BA94A9 /* uKeys.pas */; }; 61C079E411F35A300072BF46 /* EditableCellView.m in Sources */ = {isa = PBXBuildFile; fileRef = 61C079E311F35A300072BF46 /* EditableCellView.m */; }; 61D205A1127CDD1100ABD83E /* ObjcExports.m in Sources */ = {isa = PBXBuildFile; fileRef = 61D205A0127CDD1100ABD83E /* ObjcExports.m */; }; @@ -958,6 +959,8 @@ 61A4A39212A5CCC2004D81E6 /* uUtils.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uUtils.pas; path = ../../hedgewars/uUtils.pas; sourceTree = SOURCE_ROOT; }; 61A4A39312A5CCC2004D81E6 /* uVariables.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uVariables.pas; path = ../../hedgewars/uVariables.pas; sourceTree = SOURCE_ROOT; }; 61A4A3A112A5CD56004D81E6 /* uCaptions.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uCaptions.pas; path = ../../hedgewars/uCaptions.pas; sourceTree = SOURCE_ROOT; }; + 61AC067212B2E32D000B52A2 /* Appirater.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Appirater.h; path = Classes/Appirater.h; sourceTree = ""; }; + 61AC067312B2E32D000B52A2 /* Appirater.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Appirater.m; path = Classes/Appirater.m; sourceTree = ""; }; 61C079E211F35A300072BF46 /* EditableCellView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = EditableCellView.h; path = Classes/EditableCellView.h; sourceTree = ""; }; 61C079E311F35A300072BF46 /* EditableCellView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = EditableCellView.m; path = Classes/EditableCellView.m; sourceTree = ""; }; 61D2059F127CDD1100ABD83E /* ObjcExports.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ObjcExports.h; path = Classes/ObjcExports.h; sourceTree = ""; }; @@ -1076,6 +1079,8 @@ children = ( 6165929C11CA9E2F00D6E256 /* SDL_uikitappdelegate.h */, 6165929D11CA9E2F00D6E256 /* SDL_uikitappdelegate.m */, + 61AC067212B2E32D000B52A2 /* Appirater.h */, + 61AC067312B2E32D000B52A2 /* Appirater.m */, 61DE91561258B76800B80214 /* Custom UIs */, 32CA4F630368D1EE00C91783 /* Hedgewars_Prefix.pch */, 6165922911CA9BD500D6E256 /* PascalImports.h */, @@ -2412,6 +2417,7 @@ 61A4A3A212A5CD56004D81E6 /* uCaptions.pas in Sources */, 61E5D68D12AB006F00566F29 /* uLandPainted.pas in Sources */, 61F544C712AF1748007FD913 /* HoldTableViewCell.m in Sources */, + 61AC067412B2E32D000B52A2 /* Appirater.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; };