AppDelegate.m
上传用户:hechengdz
上传日期:2020-05-13
资源大小:1591k
文件大小:9k
源码类别:

iPhone

开发平台:

Objective-C

  1. /*
  2.      File: AppDelegate.m
  3.  Abstract: 
  4. This class is the application delegate. That means it receives (and should handle) messages 
  5. from the application informing it of launch and termination state. The application delegate 
  6. initiates the user interface setup and acts as a central coordinator for the database backing 
  7. the application.
  8.   Version: 1.9
  9.  
  10.  Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple
  11.  Inc. ("Apple") in consideration of your agreement to the following
  12.  terms, and your use, installation, modification or redistribution of
  13.  this Apple software constitutes acceptance of these terms.  If you do
  14.  not agree with these terms, please do not use, install, modify or
  15.  redistribute this Apple software.
  16.  
  17.  In consideration of your agreement to abide by the following terms, and
  18.  subject to these terms, Apple grants you a personal, non-exclusive
  19.  license, under Apple's copyrights in this original Apple software (the
  20.  "Apple Software"), to use, reproduce, modify and redistribute the Apple
  21.  Software, with or without modifications, in source and/or binary forms;
  22.  provided that if you redistribute the Apple Software in its entirety and
  23.  without modifications, you must retain this notice and the following
  24.  text and disclaimers in all such redistributions of the Apple Software.
  25.  Neither the name, trademarks, service marks or logos of Apple Inc. may
  26.  be used to endorse or promote products derived from the Apple Software
  27.  without specific prior written permission from Apple.  Except as
  28.  expressly stated in this notice, no other rights or licenses, express or
  29.  implied, are granted by Apple herein, including but not limited to any
  30.  patent rights that may be infringed by your derivative works or by other
  31.  works in which the Apple Software may be incorporated.
  32.  
  33.  The Apple Software is provided by Apple on an "AS IS" basis.  APPLE
  34.  MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
  35.  THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
  36.  FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
  37.  OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
  38.  
  39.  IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
  40.  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  41.  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  42.  INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
  43.  MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
  44.  AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
  45.  STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
  46.  POSSIBILITY OF SUCH DAMAGE.
  47.  
  48.  Copyright (C) 2008 Apple Inc. All Rights Reserved.
  49.  
  50.  */
  51. #import "AppDelegate.h"
  52. #import "MasterViewController.h"
  53. #import "DetailViewController.h"
  54. #import "AddViewController.h"
  55. #import "EditingViewController.h"
  56. #import "Book.h"
  57. // Private interface for AppDelegate - internal only methods.
  58. @interface AppDelegate (Private)
  59. - (void)createEditableCopyOfDatabaseIfNeeded;
  60. - (void)initializeDatabase;
  61. @end
  62. @implementation AppDelegate
  63. // Instruct the compiler to create accessor methods for the property. It will use the internal 
  64. // variable with the same name for storage.
  65. @synthesize books, window, navigationController;
  66. - (void)applicationDidFinishLaunching:(UIApplication *)application {
  67.     // The application ships with a default database in its bundle. If anything in the application
  68.     // bundle is altered, the code sign will fail. We want the database to be editable by users, 
  69.     // so we need to create a copy of it in the application's Documents directory.     
  70.     [self createEditableCopyOfDatabaseIfNeeded];
  71.     // Call internal method to initialize database connection
  72.     [self initializeDatabase];
  73.     // Add the navigation controller's view to the window
  74.     [window addSubview:navigationController.view];
  75.     [window makeKeyAndVisible];
  76. }
  77. - (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
  78.     // "dehydrate" all data objects - flushes changes back to the database, removes objects from memory
  79.     [books makeObjectsPerformSelector:@selector(dehydrate)];
  80. }
  81. - (void)dealloc {
  82.     [navigationController release];   
  83.     [window release];
  84.     [books release];
  85.     [super dealloc];
  86. }
  87. // Creates a writable copy of the bundled default database in the application Documents directory.
  88. - (void)createEditableCopyOfDatabaseIfNeeded {
  89.     // First, test for existence.
  90.     BOOL success;
  91.     NSFileManager *fileManager = [NSFileManager defaultManager];
  92.     NSError *error;
  93.     NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
  94.     NSString *documentsDirectory = [paths objectAtIndex:0];
  95.     NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:@"bookdb.sql"];
  96.     success = [fileManager fileExistsAtPath:writableDBPath];
  97.     if (success) return;
  98.     // The writable database does not exist, so copy the default to the appropriate location.
  99.     NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"bookdb.sql"];
  100.     success = [fileManager copyItemAtPath:defaultDBPath toPath:writableDBPath error:&error];
  101.     if (!success) {
  102.         NSAssert1(0, @"Failed to create writable database file with message '%@'.", [error localizedDescription]);
  103.     }
  104. }
  105. // Open the database connection and retrieve minimal information for all objects.
  106. - (void)initializeDatabase {
  107.     NSMutableArray *bookArray = [[NSMutableArray alloc] init];
  108.     self.books = bookArray;
  109.     [bookArray release];
  110.     // The database is stored in the application bundle. 
  111.     NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
  112.     NSString *documentsDirectory = [paths objectAtIndex:0];
  113.     NSString *path = [documentsDirectory stringByAppendingPathComponent:@"bookdb.sql"];
  114.     // Open the database. The database was prepared outside the application.
  115.     if (sqlite3_open([path UTF8String], &database) == SQLITE_OK) {
  116.         // Get the primary key for all books.
  117.         const char *sql = "SELECT pk FROM book";
  118.         sqlite3_stmt *statement;
  119.         // Preparing a statement compiles the SQL query into a byte-code program in the SQLite library.
  120.         // The third parameter is either the length of the SQL string or -1 to read up to the first null terminator.        
  121.         if (sqlite3_prepare_v2(database, sql, -1, &statement, NULL) == SQLITE_OK) {
  122.             // We "step" through the results - once for each row.
  123.             while (sqlite3_step(statement) == SQLITE_ROW) {
  124.                 // The second parameter indicates the column index into the result set.
  125.                 int primaryKey = sqlite3_column_int(statement, 0);
  126.                 // We avoid the alloc-init-autorelease pattern here because we are in a tight loop and
  127.                 // autorelease is slightly more expensive than release. This design choice has nothing to do with
  128.                 // actual memory management - at the end of this block of code, all the book objects allocated
  129.                 // here will be in memory regardless of whether we use autorelease or release, because they are
  130.                 // retained by the books array.
  131.                 Book *book = [[Book alloc] initWithPrimaryKey:primaryKey database:database];
  132.                 [books addObject:book];
  133.                 [book release];
  134.             }
  135.         }
  136.         // "Finalize" the statement - releases the resources associated with the statement.
  137.         sqlite3_finalize(statement);
  138.     } else {
  139.         // Even though the open failed, call close to properly clean up resources.
  140.         sqlite3_close(database);
  141.         NSAssert1(0, @"Failed to open database with message '%s'.", sqlite3_errmsg(database));
  142.         // Additional error handling, as appropriate...
  143.     }
  144. }
  145. // Save all changes to the database, then close it.
  146. - (void)applicationWillTerminate:(UIApplication *)application {
  147.     // Save changes.
  148.     [books makeObjectsPerformSelector:@selector(dehydrate)];
  149.     [Book finalizeStatements];
  150.     // Close the database.
  151.     if (sqlite3_close(database) != SQLITE_OK) {
  152.         NSAssert1(0, @"Error: failed to close database with message '%s'.", sqlite3_errmsg(database));
  153.     }
  154. }
  155. // Remove a specific book from the array of books and also from the database.
  156. - (void)removeBook:(Book *)book {
  157.     // Delete from the database first. The book knows how to do this (see Book.m)
  158.     [book deleteFromDatabase];
  159.     [books removeObject:book];
  160. }
  161. // Insert a new book into the database and add it to the array of books.
  162. - (void)addBook:(Book *)book {
  163.     // Create a new record in the database and get its automatically generated primary key.
  164.     [book insertIntoDatabase:database];
  165.     [books addObject:book];
  166. }
  167. @end