البيانات الأساسية في مكتبة ثابتة للحصول على اي فون

StackOverflow https://stackoverflow.com/questions/1711586

سؤال

لقد بنيت مكتبة ثابتة أن يجعل الاستخدام المكثف من البيانات الأساسية الإطار.أنا يمكن أن تستخدم بنجاح المكتبة في مشروع خارجي ، ولكن فقط إذا كنت تشمل .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 ملف من مجموعة المشروع بسيطة نسبيا.وهنا تافهة سبيل المثال:

  1. إنشاء جديد كسكودي مكتبة ثابتة مشروع يسمى MyStaticLibrary

  2. إنشاء .xcdatamodel الملف في MyStaticLibrary دعا MyStaticLibraryModels.xcdatamodel, إضافة بعض Entitys, ثم تولد رؤوس تطبيقات.عند بناء MyStaticLibrary الهدف ، سوف تولد libMyStaticLibrary.a ملف ثنائي ، لكنها لن تشمل تجميع .mom الملف.لذلك لابد من أن إنشاء حزمة.

  3. إنشاء بناء جديد الهدف من نوع Loadable Bundle, ، وجدت تحت MacOS X > Cocoa, دعونا نطلق الهدف الجديد MyStaticLibraryModels.

  4. السحب MyStaticLibraryModels.xcdatamodel في Compile Sources بناء المرحلة MyStaticLibraryModels الهدف.عند بناء MyStaticLibraryModels الهدف ، سوف تولد ملف يسمى MyStaticLibraryModels.bundle وسوف تحتوي على تجميع NSManagedObjectModel الملف ، MyStaticLibraryModels.mom.

  5. بعد البناء على حد سواء MyStaticLibrary و MyStaticLibraryModels أهداف السحب libMyStaticLibrary.a (جنبا إلى جنب مع أي نموذج رأس الملفات) ، MyStaticLibraryModels.bundle إلى المضيف الخاص بك المشروع ، MyAwesomeApp.

  6. MyAwesomeApp يستخدم CoreData, نفسه .xcdatamodel الملف الذي سوف تحصل على تجميعها في .أمي الملف أثناء الخاصة بناء العملية.نحن نريد أن دمج هذا .mom ملف واحد ونحن المستوردة في MyStaticLibraryModels.bundle.في مكان ما في MyAwesomeApp المشروع هناك طريقة إرجاع MyAwesomeApps NSManagedObjectModel.أبل القالب الذي تم إنشاؤه لهذا الأسلوب يبدو مثل هذا:

...

- (NSManagedObjectModel *)managedObjectModel {
  if (managedObjectModel_ != nil) {
    return managedObjectModel_;
  }
  NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"MyAwesomeApp" withExtension:@"momd"];
  managedObjectModel_ = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];    
  return managedObjectModel_;
}

ونحن سوف يغير هذا إلى دمج و عودة كل من NSManagedObjectModels ، MyAwesomApps 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 مع Entitys من كل من MyAwesomeApp و MyStaticLibrary.

لا، فإن الحد من استخدام الأطر غير التفاحية في تطبيق iPhone يغير حقا لعبة التبعية بالنسبة إلى نظام التشغيل X. معظم أطر iPhone "(مثل Toolbox من Google ل Mac، المؤامرة الأساسية، إلخ) في الواقع نوصي تتضمن المصدر في مشروع التطبيق الرئيسي الخاص بك بدلا من ربط منتج (أي مكتبة ثابتة). أعتقد أن إجماع المجتمع هو أنه، على iPhone، فلا بأس أن نتوقع من المستهلكين لإطار عملك القيام بعمل صغير "يدوي" لاستخدام مكتبتك. في حالتك، يتضمن هذا الملف Xcdatamodel في المشروع الرئيسي. كما هو الحال مع معظم الموضوع - C، أخبر المستخدمون عدم الاستفادة من تفاصيل التنفيذ واتركها في ذلك.

لدي بعض المكتبة مع Coredata أيضا. لقد وجدت هذا القالب لإدارة إطار مع إعادة تضمين الموارد

من السهل الاستخدام حقا في مشروع جديد (يصعب تطبيقه على القائمة) ولكن بالنسبة لبناء Framewoks، فهو رائع حقا :-)

https://github.com/kstenerud/ios-universal-framework.

يعمل حل 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!
}()
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top