2012-03-17 34 views
10

Tôi có một dự án Xcode cũ chứa mô hình CoreData (chứa phiên bản 1 và phiên bản 2 của mô hình). Vì nhiều lý do, tôi cần tạo một dự án Xcode mới và chuyển tất cả mã này sang dự án mới.Nhập mô hình CoreData cũ vào dự án mới

Làm cách nào để nhập/chuyển mô hình CoreData cũ của mình theo cách mà nhị phân mới này vẫn có thể đọc và có khả năng di chuyển, các kho lưu trữ CoreData hiện có trên iPhone và iPad của người dùng hiện tại của tôi thế giới? Tôi lo lắng rằng nếu tôi đẩy một phiên bản mới bằng cách sử dụng dự án mới này mà người dùng của tôi sẽ cập nhật ứng dụng của họ lên phiên bản mới nhất và sau đó nó sẽ bị lỗi vì số phiên bản mô hình hoặc mô hình không khớp.

Tôi KHÔNG nói về việc thêm phiên bản mới vào mô hình dữ liệu trong cùng một ứng dụng. Tôi hiểu quá trình đó. Đây là về việc di chuyển/nhập/etc một mô hình dữ liệu hiện có từ một dự án cũ thành một dự án mới.

Tôi có nên chỉ sao chép các tệp và thêm chúng vào dự án của mình theo cách thủ công không? Tôi có cần phải thay đổi mọi thứ trong cài đặt bản dựng của mình để tính toán không?

Trả lời

10

Cuối cùng, đây là cách tôi giải quyết nó:

  1. Tạo dự án mới với CoreData
  2. Sao chép mô hình CoreData liệu nộp qua vào dự án mới của tôi. Thêm nó vào dự án.
  3. Xóa mô hình CoreData trống được tự động xử lý bởi dự án mới.
  4. Trong Cài đặt dự án, trong Xây dựng giai đoạn, Biên dịch nguồn, tôi đã thêm tệp mô hình CoreData đã sao chép.

Sau đó, tôi đã sử dụng mã mà Scott cung cấp ở trên:

[NSManagedObjectModel mergedModelFromBundles:nil] 

đó tự động tìm tất cả các mô hình và kết hợp chúng. Bằng cách xóa một trong những tự động tạo ra và thêm một chuyển giao của tôi sau đó tất cả mọi thứ chỉ hoạt động tốt.

+0

Xin chào, vì vậy chỉ cần tải mô hình đối tượng với [NSManagedObjectModel mergedModelFromBundles: nil], tôi có thể truy xuất dữ liệu hiện có? Tôi đang cố gắng để truy vấn một bảng, nhưng nó trả về 0 và DB sqlite dường như trống. Scott đang chỉ ra mã khác này -> [[NSManagedObjectModel alloc] initWithContentsOfURL: [NSURL fileURLWithPath: modelPath]]. –

+0

Xcode 8: Tôi chỉ cần lấy một mô hình từ một dự án khác. Các bước 1-4 làm việc hoàn hảo cho tôi! – leanne

+0

@leanne, do đó, để khởi tạo dữ liệu cốt lõi và mô hình đối tượng, bạn có để lại mã mà Xcode cung cấp khi tạo dự án mới không? –

2

Miễn là bạn giữ cùng số nhận dạng ứng dụng, mã mới của bạn sẽ thay thế mã nhị phân cho người dùng đã cài đặt trong khi vẫn giữ nguyên tất cả dữ liệu của họ. Vì vậy, dự án mới của bạn về bản chất hoán đổi thành một tệp nhị phân mới. Sau đó, tùy thuộc vào bạn để đảm bảo bạn tải đúng tệp .sqlite, xử lý các nâng cấp, v.v.

Hãy để tôi chỉnh sửa thêm một chút. Downvote có một buồn.

Có bảng ZMETADATA (hoặc tương đương, không thể truy cập ngay bây giờ) có tất cả thông tin cần thiết để xác định mọi thứ. Hơn nữa có băm để biết liệu các phiên bản hiện tại có hiện diện để việc di chuyển tự động có thể xảy ra hay không. Cung cấp băm tồn tại và bạn đã tải mô hình của mình qua số [[NSManagedObjectModel alloc] initWithContentsOfURL:[NSURL fileURLWithPath:modelPath]] thay vì [NSManagedObjectModel mergedModelFromBundles:nil], thì tất cả sẽ tốt.

+0

Tôi không hỏi về cách ghi đè lên ứng dụng nhị phân của mình. Khi nhị phân mới khởi động và bắt đầu đọc kho ứng dụng hiện có, quá trình di chuyển tự động yêu cầu kho dữ liệu và đối sánh datamodel. Nếu chúng không khớp, mã CoreData sẽ ném một ngoại lệ và ứng dụng sẽ bị lỗi. –

+0

Có ... và miễn là bạn có cùng phiên bản Lõi dữ liệu của .xcdatamodeld trong ứng dụng * nhận dạng ứng dụng tương tự *, việc di chuyển sẽ xảy ra cho bạn. Chỉ cần thêm chúng vào dự án hiện tại của bạn là đủ, vâng. –

+0

Tôi không rõ mã nào sẽ hoạt động. Tôi đang cố gắng tải mô hình đối tượng với [NSManagedObjectModel mergedModelFromBundles: nil], được đề xuất bởi @KennyWyland, nhưng nó không hoạt động. Tôi cũng đã thử với [[NSManagedObjectModel alloc] initWithContentsOfURL: [NSURL fileURLWithPath: modelPath]], nhưng mọi thứ đều bị hỏng. –

-1

Tôi đã tìm thấy một cách đơn giản hơn. Tôi đã tạo một dự án mới với dữ liệu cốt lõi và sau đó đóng nó mà không cần xây dựng hoặc chạy nó. Sau đó tôi đã sử dụng một IDE để mở xcdatamodeld. Một trình soạn thảo văn bản có lẽ cũng sẽ hoạt động. Tôi phải đi sâu vào nội dung. Điều này có thể là vì tôi đang sử dụng PHPStorm và nó đang cố gắng thực hiện một dự án trong số này. Tệp mà tôi muốn chỉnh sửa trông giống như sau:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="1" systemVersion="11A491" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier=""> 
</model> 

Sau đó, tôi đã mở nguồn xcdatamoleld và sao chép mọi thứ giữa các thẻ mô hình vào tệp mới. Tôi đóng các tập tin và xây dựng dự án. Tôi đã không sao chép dữ liệu mô hình thực tế (.archiveata).

Một lưu ý: Trong dự án ban đầu của tôi, tôi đã liên tục thay đổi mô hình và xóa dữ liệu mô hình. Xcode không thể xử lý nó và đã ném ra nhiều lỗi khác nhau. Lần cuối cùng tôi làm điều đó, tôi nhận được cảnh báo:

CoreData: warning: Unable to load class named 'Performance' for entity 'Performance'. Class not found, using default NSManagedObject instead. 

Cảnh báo này được tái xuất hiện trong dự án mới nên có sự cố trong định nghĩa mô hình. May mắn thay, nó không gây ra bất kỳ vấn đề với việc thực hiện. Nếu bạn không có cảnh báo này, bạn có thể bị phạt.

Điều này là với Xcode 8.2.1 và đó là một dự án Swift.

+1

Chỉnh sửa nội bộ tập tin là cách chắc chắn để giới thiệu ma quỷ và vặn vẹo trong dự án của bạn. Bạn nên để Xcode kiểm soát những thứ đó cho bạn, đặc biệt là vì chúng có thể thay đổi từ phiên bản này sang phiên bản khác. –

+0

OP đã hỏi về việc nhập một mô hình hiện có vào một dự án mới. Không có gì để 'vặn'. Ngay cả khi nó không hoạt động, chỉ cần xóa dự án mới và tạo một dự án khác. Tôi có một dự án thứ hai nằm xa trong sự phát triển của nó. Tôi sẽ không phương pháp này trên đó. Nếu Apple cung cấp các phương thức để nhập một mô hình hiện có, chúng tôi sẽ không cần bài đăng này. – curt

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