البيانات الأساسية في مكتبة ثابتة للحصول على اي فون
-
19-09-2019 - |
سؤال
لقد بنيت مكتبة ثابتة أن يجعل الاستخدام المكثف من البيانات الأساسية الإطار.أنا يمكن أن تستخدم بنجاح المكتبة في مشروع خارجي ، ولكن فقط إذا كنت تشمل .xcdatamodel الملف في المشروع الرئيسي.وهذا هو أقل من مثالية ، لأن الهدف من المكتبة إلى إخفاء تفاصيل التنفيذ إلى أقصى حد ممكن.
في فصل السؤال, علمت أن لا حزمة الموارد مع مكتبة (الذي يجعل المعنى الكامل لي الآن).
لذا هل هناك طريقة برمجيا تسمح نموذج 'اكتشاف' دون الحاجة إلى تضمين نموذج الرئيسية في المشروع ؟
المحلول
كما أنشأت مكتبة ثابتة الخاصة التي تستخدم البيانات الأساسية. إلى جانب المكتبة الثابتة لدي هدف آخر في المشروع حيث لدي عنصر موارد حزمة نسخ، يقوم بنسخ بعض الصور والأشياء من هذا القبيل في الحزمة ومصادر الترجمة، حيث أقوم بتجميع xcdatamodel.
سوف تحتوي الحزمة الأخيرة على جميع الملفات اللازمة. في مشروعك الرئيسي يعتمد على المكتبة الثابتة، عليك تضمين تلك الحزمة أيضا. سيكون للمشروع الرئيسي الآن الوصول إلى ملف MOM اللازم لاستخدام البيانات الأساسية.
لاستخدام البيانات الأساسية مع MOM من الحزمة، عليك إنشاء نموذج كائن مدار دمج في التعليمات البرمجية (قد يكون المشروع الرئيسي يحتوي على بعض طراز البيانات الأساسية أيضا):
- (NSManagedObjectModel *) mergedManagedObjectModel
{
if (!mergedManagedObjectModel)
{
NSMutableSet *allBundles = [[[NSMutableSet alloc] init] autorelease];
[allBundles addObjectsFromArray: [NSBundle allBundles]];
[allBundles addObjectsFromArray: [NSBundle allFrameworks]];
mergedManagedObjectModel = [[NSManagedObjectModel mergedModelFromBundles: [allBundles allObjects]] retain];
}
return mergedManagedObjectModel;
}
فقط بما في ذلك الحزمة لن تضطر إلى إعطاء XCDATAMODEL، يجب تضمين ملف Mom المترجمة فقط.
نصائح أخرى
ساشا الجواب على المسار الصحيح.دمج مترجمة .mom
ملف من مكتبة ثابتة في .mom
ملف من مجموعة المشروع بسيطة نسبيا.وهنا تافهة سبيل المثال:
إنشاء جديد كسكودي مكتبة ثابتة مشروع يسمى
MyStaticLibrary
إنشاء .xcdatamodel الملف في
MyStaticLibrary
دعاMyStaticLibraryModels.xcdatamodel
, إضافة بعضEntity
s, ثم تولد رؤوس تطبيقات.عند بناءMyStaticLibrary
الهدف ، سوف تولدlibMyStaticLibrary.a
ملف ثنائي ، لكنها لن تشمل تجميع.mom
الملف.لذلك لابد من أن إنشاء حزمة.إنشاء بناء جديد الهدف من نوع
Loadable Bundle
, ، وجدت تحتMacOS X > Cocoa
, دعونا نطلق الهدف الجديدMyStaticLibraryModels
.السحب
MyStaticLibraryModels.xcdatamodel
فيCompile Sources
بناء المرحلةMyStaticLibraryModels
الهدف.عند بناءMyStaticLibraryModels
الهدف ، سوف تولد ملف يسمىMyStaticLibraryModels.bundle
وسوف تحتوي على تجميعNSManagedObjectModel
الملف ،MyStaticLibraryModels.mom
.بعد البناء على حد سواء
MyStaticLibrary
وMyStaticLibraryModels
أهداف السحبlibMyStaticLibrary.a
(جنبا إلى جنب مع أي نموذج رأس الملفات) ،MyStaticLibraryModels.bundle
إلى المضيف الخاص بك المشروع ،MyAwesomeApp
.MyAwesomeApp
يستخدمCoreData
, نفسه.xcdatamodel
الملف الذي سوف تحصل على تجميعها في .أمي الملف أثناء الخاصة بناء العملية.نحن نريد أن دمج هذا.mom
ملف واحد ونحن المستوردة فيMyStaticLibraryModels.bundle
.في مكان ما فيMyAwesomeApp
المشروع هناك طريقة إرجاعMyAwesomeApp
sNSManagedObjectModel
.أبل القالب الذي تم إنشاؤه لهذا الأسلوب يبدو مثل هذا:
...
- (NSManagedObjectModel *)managedObjectModel {
if (managedObjectModel_ != nil) {
return managedObjectModel_;
}
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"MyAwesomeApp" withExtension:@"momd"];
managedObjectModel_ = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
return managedObjectModel_;
}
ونحن سوف يغير هذا إلى دمج و عودة كل من NSManagedObjectModel
s ، MyAwesomApp
s MyStaticLibraryModels
, بوصفها واحدة ، جنبا إلى جنب NSManagedObjectModel
مثل ذلك:
- (NSManagedObjectModel *)managedObjectModel {
if (managedObjectModel_ != nil) {
return managedObjectModel_;
}
NSMutableArray *allManagedObjectModels = [[NSMutableArray alloc] init];
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"MyAwesomeApp" withExtension:@"momd"];
NSManagedObjectModel *projectManagedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
[allManagedObjectModels addObject:projectManagedObjectModel];
[projectManagedObjectModel release];
NSString *staticLibraryBundlePath = [[NSBundle mainBundle] pathForResource:@"MyStaticLibraryModels" ofType:@"bundle"];
NSURL *staticLibraryMOMURL = [[NSBundle bundleWithPath:staticLibraryBundlePath] URLForResource:@"MyStaticLibraryModels" withExtension:@"mom"];
NSManagedObjectModel *staticLibraryMOM = [[NSManagedObjectModel alloc] initWithContentsOfURL:staticLibraryMOMURL];
[allManagedObjectModels addObject:staticLibraryMOM];
[staticLibraryMOM release];
managedObjectModel_ = [NSManagedObjectModel modelByMergingModels:allManagedObjectModels];
[allManagedObjectModels release];
return managedObjectModel_;
}
هذا سيعود اندمجت NSManagedObjectModel
مع Entity
s من كل من MyAwesomeApp
و MyStaticLibrary
.
لا، فإن الحد من استخدام الأطر غير التفاحية في تطبيق iPhone يغير حقا لعبة التبعية بالنسبة إلى نظام التشغيل X. معظم أطر iPhone "(مثل Toolbox من Google ل Mac، المؤامرة الأساسية، إلخ) في الواقع نوصي تتضمن المصدر في مشروع التطبيق الرئيسي الخاص بك بدلا من ربط منتج (أي مكتبة ثابتة). أعتقد أن إجماع المجتمع هو أنه، على iPhone، فلا بأس أن نتوقع من المستهلكين لإطار عملك القيام بعمل صغير "يدوي" لاستخدام مكتبتك. في حالتك، يتضمن هذا الملف Xcdatamodel في المشروع الرئيسي. كما هو الحال مع معظم الموضوع - C، أخبر المستخدمون عدم الاستفادة من تفاصيل التنفيذ واتركها في ذلك.
لدي بعض المكتبة مع Coredata أيضا. لقد وجدت هذا القالب لإدارة إطار مع إعادة تضمين الموارد
من السهل الاستخدام حقا في مشروع جديد (يصعب تطبيقه على القائمة) ولكن بالنسبة لبناء Framewoks، فهو رائع حقا :-)
يعمل حل Sascha Konietzke بشكل جيد، ولكن هناك تحذير مهم يحتاج إلى توفيره لعمله. يحتاج الحزمة التي تحتوي على النموذج إلى تحميلها أولا، وإلا فلن يتم تضمينها في الصفيف ودمجها في MOM.
في حالته، ربما تم الوصول إلى الموارد بالفعل من الحزمة، لذلك تم تحميل الحزمة بالفعل قبل تنفيذ هذا الرمز.
إجابة Prairiedogg قديمة قليلا، إليك برنامج تعليمي للقيام بذلك في Xcode 5: http://bharathnagarajra.wordpress.com/2017/02/14/working-core-core-data-in-a-static-library/
لاحظ أنه بدلا من استخدام ملف Xcdatamodel / Mom، يمكنك أيضا إنشاء النموذج الخاص بك في التعليمات البرمجية (خاصة إذا كان لديك نموذج بسيط) بهذه الطريقة لن تحتاج إلى إنشاء حزمة إضافية للموارد. إليك مثال بسيط مع جدول واحد يحتوي على خصمين:
- (NSManagedObjectModel *)coreDataModel
{
NSManagedObjectModel *model = [NSManagedObjectModel new];
NSEntityDescription *eventEntity = [NSEntityDescription new];
eventEntity.name = @"EventEntity";
eventEntity.managedObjectClassName = @"EventEntity";
NSAttributeDescription *dateAttribute = [NSAttributeDescription new];
dateAttribute.name = @"date";
dateAttribute.attributeType = NSDateAttributeType;
dateAttribute.optional = NO;
NSAttributeDescription *typeAttribute = [NSAttributeDescription new];
typeAttribute.name = @"type";
typeAttribute.attributeType = NSStringAttributeType;
typeAttribute.optional = NO;
eventEntity.properties = @[dateAttribute, typeAttribute];
model.entities = @[eventEntity];
return model;
}
فيما يلي برنامج تعليمي حول إنشاء نموذج من التعليمات البرمجية: https://www.cocoanetics.com/2012/04/creating-a-coredata-model-in-code/
بناء على هذا النهج، قمت بإنشاء مكتبة صغيرة وسهلة الاستخدام قد تناسب احتياجاتك lsminidb. حتى تتمكن من التحقق من ذلك أيضا.
نسخة SWIFT 2 إجابة SASCHA:
lazy var managedObjectModel: NSManagedObjectModel = {
// The managed object model for the application. This property is not optional. It is a fatal error for the application not to be able to find and load its model.
var allBundles = NSMutableSet()
allBundles.addObjectsFromArray(NSBundle.allBundles())
allBundles.addObjectsFromArray(NSBundle.allFrameworks())
let model = NSManagedObjectModel.mergedModelFromBundles(allBundles.allObjects as? [NSBundle])
return model!
}()