2013-05-02 36 views
5

Trong ứng dụng của tôi, tôi đã sử dụng DB sqlite. Tôi đã gửi phiên bản 1.0 của ứng dụng tới cửa hàng ứng dụng. Nhưng sau đó tôi đã thực hiện một số thay đổi vào DB như Chèn một số hàng mới.Sao chép cơ sở dữ liệu đã cập nhật vào thiết bị trong ios sdk

Sau đó, gửi phiên bản 1.1 của ứng dụng. But i will not able to get updated DB because the old DB already exists in device.

Làm cách nào tôi có thể giải quyết vấn đề này?

Nếu tôi xóa ứng dụng & thì hãy cài đặt phiên bản ứng dụng mới, sau đó tôi đã cập nhật DB.

//My code for copy of DB is as follow: 

- (void)createEditableCopyOfDatabaseIfNeeded 
{ 
    // First, test for existence. 
    BOOL success; 
    NSFileManager *fileManager = [NSFileManager defaultManager]; 
    NSError *error; 
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentsDirectory = [paths objectAtIndex:0]; 
    NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:@"xxx.sqlite"]; 
    success = [fileManager fileExistsAtPath:writableDBPath]; 
    if (success) return; 

    // The writable database does not exist, so copy the default to the appropriate location. 

    NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"xxx.sqlite"]; 
    success = [fileManager copyItemAtPath:defaultDBPath toPath:writableDBPath error:&error]; 
    if (!success) { 
     NSAssert1(0, @"Failed to create writable database file with message '%@'.", [error localizedDescription]); 
    } 
} 

Tôi gọi phương thức này trong phương pháp appDidFinishLaunching.

Làm thế nào tôi có thể được cập nhật DB mà không xóa các ứng dụng khi phiên bản mới có sẵn

Trả lời

5

Bạn có thể sử dụng NSUserDefaults để thực hiện việc này.

Trong phiên bản mới của bạn thêm mã này:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{ 
    if(![[NSUserDefaults standardUserDefaults] boolForKey:@"1.1"]]) 
    { 
    [self removeDatabase]; 
    [self createEditableCopyOfDatabaseIfNeeded]; 
    [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"1.1"]; 
    } 
    //Other stuffs 
} 

Phương pháp để loại bỏ các tập tin cơ sở dữ liệu cũ:

- (void)removeDatabase 
{ 
    BOOL success; 
    NSFileManager *fileManager = [NSFileManager defaultManager]; 
    NSError *error; 
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentsDirectory = [paths objectAtIndex:0]; 
    NSString *removeDBPath = [documentsDirectory stringByAppendingPathComponent:@"xxx.sqlite"]; 
    success = [fileManager fileExistsAtPath:writableDBPath]; 
    if(success) 
    { 
     [fileManager removeItemAtPath:writableDBPath error:&error] 
    } 
} 
+0

Cảm ơn rất nhiều! Wow, thật tuyệt vời khi làm điều này rất dễ dàng. – AtWork

0

Bạn sẽ cần phải thực hiện một sự chuyển đổi cơ sở dữ liệu để người dùng cũ của ứng dụng của bạn không bị mất dữ liệu của họ.

Điều này có nghĩa là kiểm tra phiên bản của cơ sở dữ liệu đã tồn tại và thực thi các câu lệnh SQL cần thiết để cập nhật lược đồ và dữ liệu.

Các MTMigration khuôn khổ (MIT giấy phép) có thể giúp bạn thực thi mã một lần mỗi phiên bản của ứng dụng của bạn, ví dụ:

[MTMigration migrateToVersion:@"1.1" block:^{ 
    // migrate the SQL database here 
}]; 

Nhưng bạn có thể muốn để phát hiện các phiên bản của cơ sở dữ liệu của bạn khác nhau.

Sẽ là một ý tưởng hay khi viết một số xét nghiệm đơn vị cho quy trình này. Nén dữ liệu người dùng là điều cuối cùng bạn muốn làm.

+0

Cảm ơn bạn đã trả lời! Vì vậy, tôi nên viết tất cả các truy vấn lập trình? – AtWork

+0

Bạn có thể đặt SQL trực tiếp vào mã nguồn của bạn hoặc giữ nó trong các tệp .sql để quản lý dễ dàng hơn, sau đó bạn tải trong thời gian chạy. –

+0

Vì vậy, Theo bạn, nếu tôi muốn chèn một số hàng mới trong DB, tôi phải thực hiện các truy vấn mới lập trình thay vì chỉ thêm trực tiếp vào sql DB. – AtWork

0

Bạn phải viết dữ liệu kịch bản di cư: -

Trong trường hợp khi bạn cần thực hiện thay đổi đối với bảng thoát có chứa một số dữ liệu, sau đó bạn cần thực hiện một số bước như sau:

1) Đổi tên bảng hiện

Say TableName là 'testtable', Vì vậy, Đổi tên bảng để 'TestTableOld'

2) Tạo một bảng mới có tên gọi 'testtable' trong đó có các cột mới mà bạn muốn và khác làm thay đổi.

3) Sao chép dữ liệu từ 'TestTableOld' thành 'testtable' với truy vấn như:

Chèn vào testtable ('col1, col2' ... 'coln') Giá trị col1 Chọn, col2, col3, ...'coln' Từ TestTableOld;

Và giá trị bộ cột mới được thêm làm trống, vì đối với các mục nhập mới sẽ sử dụng như vậy.

4) Thả bảng 'TestTableOld'

Thực hiện theo các thủ tục trên bốn bước như thế này sẽ làm việc như một tuyên bố thụ và cũng có thể nó sẽ bảo vệ tất cả các dữ liệu của bạn từ bảng gốc của bạn.

Nếu bạn đang sử dụng User_Version, sau đó sẽ hữu ích để xác định DB cũ với DB mới

Các vấn đề liên quan