# This file is part of NIT ( http://www.nitlanguage.org ). # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Basic structure for Nit apps on iOS module app import platform import ::app in "ObjC Header" `{ #import // Our interface to the iOS system @interface AppDelegate: UIResponder // The main window @property (strong, nonatomic) UIWindow *window; @end `} in "ObjC" `{ // Global reference to the App from app.nit App app_nit_ios_app; // Our own C argc and argv int app_nit_ios_argc; char **app_nit_ios_argv; @implementation AppDelegate - (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Set aside `application` to be used from Nit App_ui_application__assign(app_nit_ios_app, application); App_app_delegate__assign(app_nit_ios_app, self); // Complete the callback return App_will_finish_launching_with_options(app_nit_ios_app); } - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { return App_did_finish_launching_with_options(app_nit_ios_app); } - (void)applicationWillResignActive:(UIApplication *)application { App_will_resign_active(app_nit_ios_app); } - (void)applicationDidEnterBackground:(UIApplication *)application { App_did_enter_background(app_nit_ios_app); } - (void)applicationWillEnterForeground:(UIApplication *)application { App_will_enter_foreground(app_nit_ios_app); } - (void)applicationDidBecomeActive:(UIApplication *)application { App_did_become_active(app_nit_ios_app); } - (void)applicationWillTerminate:(UIApplication *)application { App_will_terminate(app_nit_ios_app); } @end `} # Application interface to the iOS system extern class AppDelegate in "ObjC" `{ AppDelegate * `} end # Graphical application to which events are sent extern class UIApplication in "ObjC" `{ UIApplication * `} end redef class App # Main graphical application var ui_application: UIApplication # Application interface to the iOS system var app_delegate: AppDelegate # Copy back to C the command line arguments # # Nit extracts the first arguments from the `args` sequence, # so we need to add it back. That's why Nit's `args` is smaller than in C. private fun register_args(program_name: NativeString, argc: Int, argv: Sequence[String]) import Sequence[String].[], String.to_cstring in "ObjC" `{ app_nit_ios_argc = argc+1; // TODO copy or pin the strings when needed app_nit_ios_argv = malloc(argc * sizeof(char*)); app_nit_ios_argv[0] = program_name; for (int i = 0; i < argc; i ++) { String arg = Sequence_of_String__index(argv, i); app_nit_ios_argv[i+1] = String_to_cstring(arg); } `} # Register `self` globally in C so it can be retrieved from iOS callbacks private fun register_globally in "ObjC" `{ App_incr_ref(recv); app_nit_ios_app = recv; `} # Entry point to the iOS framework private fun ui_application_main: Bool import did_finish_launching_with_options, will_finish_launching_with_options, will_resign_active, did_enter_background, will_enter_foreground, did_become_active, will_terminate, ui_application=, app_delegate= in "ObjC" `{ @autoreleasepool { return UIApplicationMain(app_nit_ios_argc, app_nit_ios_argv, nil, NSStringFromClass([AppDelegate class])); } `} # The application is about to launch # # Redef this method to set the very first custom code to be executed. fun will_finish_launching_with_options: Bool do return true # The application just launched but is not yet displayed to the user # # Redef this method to customize the behavior. fun did_finish_launching_with_options: Bool do return true # The application is about to move from active to inactive state # # This can occur for certain types of temporary interruptions # (such as an incoming phone call or SMS message) or when the # user quits the application and it begins the transition to # the background state. # # Redef this method to pause ongoing tasks, disable timers, and # throttle down OpenGL ES frame rates. Games should use this # method to pause. fun will_resign_active do end # The application just left foreground it can be suspended at any time # # Redef this method to release shared resources, save user data, # invalidate timers, and store application state to restore your # application to its current state in case it is terminated later. # # If your application supports background execution, this method # is called instead of `will_terminate` when the user quits. fun did_enter_background do end # The application will enter the foreground # # Called as part of the transition from the background to the # inactive state. # # Redef to und changes made on entering the background. fun will_enter_foreground do end # The application just became active # # Redef to restart any tasks that were paused (or not yet started) while # the application was inactive. If the application was previously # in the background, optionally refresh the user interface. fun did_become_active do end # The application is about to terminate (not suspended) # # Redef to save data if appropriate. fun will_terminate do end end app.register_args(program_name.to_cstring, args.length, args) app.register_globally var ret = app.ui_application_main exit if ret then 0 else 1