Xcode 8 генерирует сломанные подклассы NSManagedObject для iOS 10


Я недавно обновил свой проект приложения iOS до iOS 10. Теперь я пытаюсь изменить основную модель данных моего приложения, но новые подклассы NSManagedObject, которые генерирует Xcode, сломаны. Я также пытался исправить руководство по подклассам, но это не работает.

минимальная версия инструментов для базовой модели данных установлена на Xcode 7.0, а язык генерации кода-на Swift.

это код, который генерирует Xcode:

import Foundation
import CoreData
import 

extension Group {

    @nonobjc public class func fetchRequest() -> NSFetchRequest {
        return NSFetchRequest(entityName: "Group");
    }

    @NSManaged public var name: String?
    @NSManaged public var platform: NSNumber?
    @NSManaged public var profiles: NSOrderedSet?

}

// MARK: Generated accessors for profiles
extension Group {

    @objc(insertObject:inProfilesAtIndex:)
    @NSManaged public func insertIntoProfiles(_ value: SavedProfile, at idx: Int)

    @objc(removeObjectFromProfilesAtIndex:)
    @NSManaged public func removeFromProfiles(at idx: Int)

    @objc(insertProfiles:atIndexes:)
    @NSManaged public func insertIntoProfiles(_ values: [SavedProfile], at indexes: NSIndexSet)

    @objc(removeProfilesAtIndexes:)
    @NSManaged public func removeFromProfiles(at indexes: NSIndexSet)

    @objc(replaceObjectInProfilesAtIndex:withObject:)
    @NSManaged public func replaceProfiles(at idx: Int, with value: SavedProfile)

    @objc(replaceProfilesAtIndexes:withProfiles:)
    @NSManaged public func replaceProfiles(at indexes: NSIndexSet, with values: [SavedProfile])

    @objc(addProfilesObject:)
    @NSManaged public func addToProfiles(_ value: SavedProfile)

    @objc(removeProfilesObject:)
    @NSManaged public func removeFromProfiles(_ value: SavedProfile)

    @objc(addProfiles:)
    @NSManaged public func addToProfiles(_ values: NSOrderedSet)

    @objc(removeProfiles:)
    @NSManaged public func removeFromProfiles(_ values: NSOrderedSet)

}

редактировать: это конкретные ошибки, которые дает Xcode:

1. Group+CoreDataProperties.swift:13:1: Expected identifier in import declaration (the empty import)
2. Group+CoreDataProperties.swift:13:11: 'Group' is ambiguous for type lookup in this context
3. Group+CoreDataProperties.swift:15:16: Cannot specialize non-generic type 'NSFetchRequest'
4. Group+CoreDataProperties.swift:26:11: 'Group' is ambiguous for type lookup in this context
4. Group+CoreDataProperties.swift:43:82: 'SavedProfile' is ambiguous for type lookup in this context
20 58

20 ответов:

я наконец-то получил свою работу. Вот что я сделал. (Полеты-одна из моих сущностей)

Я устанавливаю xcdatamodeld следующим образом

enter image description here

и тогда сущность как

enter image description here

затем я использовал редактор -> создать NSManagedObject подкласс

это создает два файла для моих полетов сущность

Рейсы + CoreDataProperties.Свифт

Полеты + CoreDataClass.Свифт

я переименовал рейсы + CoreDataClass.стремительный к полетам.Свифт

рейсы.Свифт-это просто

import Foundation
import CoreData

@objc(Flights)
public class Flights: NSManagedObject {

}

Рейсы + CoreDataProperties.Свифт-это

import Foundation
import CoreData


extension Flights {

    @nonobjc public class func fetchRequest() -> NSFetchRequest<Flights> {
        return NSFetchRequest<Flights>(entityName: "Flights");
    }

    @NSManaged public var ...
}

Это, кажется, работает для меня.Я не мог заставить Codegen работать каким-либо другим способом, хотя я пробовал многие из предложений, которые были там.

также это заставило меня почесать голову на некоторое время, и я добавляю его в качестве помощи. Не забывайте, что с новой версией Generics FetchRequest вы можете сделать это

let fetchRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest(entityName: "Flights")

Я считаю, что причина, по которой вы столкнулись с этими ошибками после создания файлов подкласса NSManagedObject, может быть связана с опцией Codegen, которая была выбрана во время изменения модели данных.

Я не думаю, что это ошибка. По крайней мере, не в Xcode 8.1 (8B62).

я столкнулся с подобной проблемой и исправил ее, изменив параметр Codegen на "Manual/None" и оставив параметр модуля как "глобальное пространство имен". Затем я сгенерировал файлы подкласса NSManagedObject. Однако в зависимости от ситуации вам может даже не понадобиться создавать подклассы NSManagedObject.

Ниже приведены более подробные сведения о параметрах entity Codegen на основе моего обзора документации Apple, форума разработчиков Apple и тестирования с моим собственным проектом.

Вариант 1: "Определение Класса"

  • думайте об этом как о опции "подключи и играй"

  • используйте редактор моделей для создания лиц и связанные с ними атрибуты что вы хотите управлять основными данными.

  • не используйте генератор подклассов NSMangagedObject. Необходимое файлы автоматически генерируются с помощью Xcode (однако они не отображается в навигаторе проекта).

  • если вы создаете файлы NSManagedObject, Apple сообщает вам, что эти файлы не должны редактироваться в комментариях заголовка сказанного файлы. Если вам нужно отредактировать эти файлы, то это хороший признак что вам нужно использовать другой вариант Codegen.

  • оставьте параметры класса по умолчанию для вашего объекта (Module = Global Пространство имен и Codegen = определение класса)

  • Если вам нужно переопределить методы NSManagedObject, вы можете создайте расширение, используя имя в параметре Class.

    // Optional extension in Entity.swift extension Entity { // Override NSManagedObject methods }

Параметры 2: "Руководство/Нет"

  • аналогичен варианту 1, за исключением того, что вы можете видеть и редактировать Файлы подкласса NSManagedObject.

  • используйте редактор моделей для создания объектов и связанных атрибутов что вы хотите управлять основными данными.

  • перед использованием генератора подклассов NSManagedObject установите Кодген опция "вручную / нет" для объекта. Модуль должен быть Глобальный Пространство имен.

  • после добавления/удаления / обновления атрибута у вас есть два варианта: (1) Вручную обновите файлы NSManagedObject, созданные для вас Или (2) снова используйте генератор подклассов NSManagedObject (это будет обновите только Entity+CoreDataProperties.swift file).

  • опять же, если вам нужно переопределить и методы из NSManagedObject, вы можно создать расширение. Расширение должно быть создано в этот Сущность+CoreDataClass.SWIFT файл и не Сущность+CoreDataProperties.Свифт файл (этот файл может быть обновлен из-за для изменения редактора модели).

    // Optional extension in Entity+CoreDataClass.swift extension Entity { // Override NSManagedObject methods }

Вариант 3: "Категория/Расширение"

  • используйте эту опцию, если у вас есть пользовательские свойства, которые не должны быть управляется основными данными.

  • используйте редактор моделей для создания объектов и связанных атрибутов что вы хотите Основные данные для управления.

  • убедитесь, что параметр модуль установлен в текущий модуль продукта и Параметр Codegen имеет значение "категория / расширение".

  • создайте свой собственный подкласс NSManagedObject со свойствами, которые вы будет самостоятельно управлять.

  • не используйте генератор подклассов NSMangagedObject. Необходимое файлы автоматически генерируются с помощью Xcode (однако они не отображается в вашем проекте навигатор.)

    // Subclass NSManagedObject in Entity.swift class Entity: NSManagedObject { // Self managed properties }

    // Optional extension in Entity.swift extension Entity { // Override NSManagedObject methods }

  1. чтобы решить эту проблему, удалите производные данные приложения.

  2. затем измените модуль до Текущий Модуль Продукта, а также внести изменения в Codegen до Руководство/Нет.

  3. List item

попробуйте установить CodeGen: Manual / None Модуль: Текущий Модуль Продукта

Он работал для меня хорошо, когда я столкнулся с той же проблемой.

enter image description here

вы можете попробовать эти шаги

  1. выберите .xcdatamodeld файл в навигаторе проекта Xocde
  2. на Модуль Данных Инспектор, убедится Codegen:Руководство/Нет
  3. затем Edit -> Создать Подкласс NSManagedObject
  4. очистить продукт и восстановить

это работает? Если нет

убедитесь, что вы все класс имеет не то же самое имя с объекты. Вы можете найти эти классы в Собрать Фаз ->Компилировать Источники. Переименуйте класс или сущности, если они дублируются

или

вы можете запустить эту команду в папке проекта, чтобы получить дополнительную информацию об ошибке

xcodebuild -verbose

Я получил это сообщение, когда у меня эта проблема

дубликат символа _OBJC_CLASS_$_RandomList в:

xxxx / RandomList.o

xxxx / RandomList+CoreDataClass.o

RandomList.h и RandomList + CoreDataClass.h иметь тот же символ при компиляции

Я думаю, что почему Xcode не предупредил вас, но компилятор выдаст ошибку

надеюсь, что это поможет вам

Если у вас есть устаревшие приложения, и вы хотите продолжать добавлять классы управляемых объектов вручную

  1. убедитесь, что для вашей основной модели данных codegen установлено значение Руководство/Нет
  2. Выберите файл модели основных данных
  3. создать подкласс управляемых объектов

screenshot of editor

удалить 3-й import заявление, потому что он пуст.

примечание: Я не знаю, почему это происходит, но я думаю, что это ошибка в Xcode 8. Просто удалите его и он будет работать нормально.

On Xcode 8.2.1, Я сделал это так: (Спасибо Даниил Чепенко)

enter image description here

но Xcode 8.2.1 добавлю тупой . в созданные файлы:

enter image description here

просто удалить . и он будет работать правильно.

У меня просто возникла проблема, когда я только что добавил объект Person в своей модели в шаблон Core Data. Затем сгенерировал подкласс NSManagedObject для этого, и он не будет компилироваться, давая мне ошибку компоновщика. Оказывается, я должен изменить параметр Codegen на Manual / None, чтобы заставить его работать (см. нижнюю правую часть изображения).enter image description here

Я думаю,что это проблема xcode, где xcode генерирует неправильный синтаксис для класса категории основных данных. Я создаю nsmanageobjectsubclass для одного субъекта AgentDetails It is creating the following classes

здесь xcode создает неправильную структуру кода в AgentDetails+CoreDataClass.h и AgentDetails+CoreDataClass.m. Они имеют структуру кода, как:

enter image description here

и

enter image description here

таким образом, он имеет дубликат проблемы интерфейса как AgentDetails.h есть же взаимодействие.

сейчас, чтобы исправить это, вы должны изменить код AgentDetails+CoreDataClass.h

enter image description here

и AgentDetails+CoreDataClass.m такой:

enter image description here

в Инспекторе модели данных выберите текущий модуль продукта в разделе "модуль" и руководство/нет в разделе "Codegen". (Это позволяет редактировать файлы подклассов и восстанавливать свойства CoreDataProperties.swift при изменении атрибутов под одной и той же сущностью.)

enter image description here

затем вы можете выбрать Создать NSManagedObjectSubclass в меню редактора. Xcode создаст для вас 2 файла YourEntity+CoreDataClass.swift и YourEntity+CoreDataProperties.быстрый. Обратите внимание, если у вас нет последнего Xcode (8.2.1), любые необязательные/неоперативные свойства, которые вы установили в Инспекторе моделей, не будут отображаться правильно. Вы можете редактировать в YourEntity +CoreDataProperties.быстрый файл.

Xcode 8.1, похоже, генерирует класс модели внутри. Просто удалите 2 созданных класса, и вы все равно сможете использовать сущности в своем коде.

вот сообщение об ошибке я получил

<unknown>:0: error: filename "Recipe+CoreDataProperties.swift" used twice: '/Users/Rick/Desktop/Devslop/Rick Recipe/Recipe+CoreDataProperties.swift' and '/Users/Rick/Library/Developer/Xcode/DerivedData/Rick_Recipe-cctgjudvqobxlwetbcwmzrgxigwg/Build/Intermediates/Rick Recipe.build/Debug-iphonesimulator/Rick Recipe.build/DerivedSources/CoreDataGenerated/Rick_Recipe/Recipe+CoreDataProperties.swift'
<unknown>:0: note: filenames are used to distinguish private declarations with the same name
Command /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swiftc failed with exit code 1

кроме того, если вы добавляете подкласс NSManagedObject самостоятельно, не забудьте выполнить следующий шаг: Обратиться.' xcdatamodeld '- > Выберите объект - > показать инспектор модели данных - > Codegen - > выберите "руководство / нет"

Это работает для меня.

Я нашел это сообщение от Дэвида Аткинсона что в некотором роде полезно. Если я создам код так, как описал Дэвид. Я просто получаю код с некоторыми синтаксическими ошибками, и если я исправляю ошибки, все работает как раньше. Отсутствуют файлы, начинающиеся с '.' уже.

синтаксические ошибки, которые я должен исправить - ненужный импорт - и некоторые публичные свойства, которые не предназначены для публичного использования в моем коде

Я запускаю последнюю версию бета-версии Xcode 8.1 (8T47).

согласно журналу ошибок (см. ниже), создаются две копии автоматически созданных файлов. Одна копия помещается в папку проекта Xcode (которая отображается в вашем каталоге на левой панели инструментов Xcode), а вторая копия создается в папке DerivedData для вашего проекта:

/Users/<your name>/Library/Developer/Xcode/DerivedData/<your app>-axhtnodotznxnrenefflktnxfeal/Build/Intermediates/<your app>.build/Debug-iphonesimulator/<your app>.build/DerivedSources/CoreDataGenerated/<your app>/<class name>+CoreDataProperties.swift
/Users/<your name>/Library/Developer/Xcode/DerivedData/<your app>-axhtnodotznxnrenefflktnxfeal/Build/Intermediates/<your app>.build/Debug-iphonesimulator/<your app>.build/DerivedSources/CoreDataGenerated/<your app>/<class name>+CoreDataClass.swift

удаление копий в каталоге проекта Xcode устранит все проблемы, но окажется бессмысленным, как вы можете больше не редактируйте эти файлы...

Я бы не сказал, что это решение, а просто наполовину осел способ получить проект для сборки. Надеюсь, эта ошибка будет решена в ближайшее время.

Error Log

для меня я создал классы CocoaTouch путем подклассов NSManagedObject вручную. Я установил модуль в качестве текущего модуля продукта и Codegen в качестве категории / расширения, и он хорошо работает.

в моем конкретном случае я добавил CoreData к существующему проекту, который уже имел класс модели с тем же именем, что и моя сущность. Удаление старого класса модели исправило проблему, так как его тип сталкивался с новым классом сущности CoreData.

Что вам нужно сделать, это установить CodeGen в категорию / расширение перед выполнением подклассов Create NSManagedObject.

У меня есть объект Flights, и эти настройки в Инспекторе модели данных работали для меня:

  1. установите имя в nothing (вы увидите какой-то серый текст "NSManagedObject"). Значение по умолчанию будет записано как" полеты", просто удалите это.

  2. ничего в модуле."Глобальное пространство имен" выделено серым цветом - это то, что вы увидите.

  3. Codegen в ручную/нет.

  4. Затем Перейти Редактор - > Создать Подкласс NSManagedObject для создания файлов swift

  5. переименовать рейсы + CoreDataClass.Свифт просто полеты.Свифт

вот ссылка на скриншот (по какой-то причине imgur отвергал его: ( ) https://drive.google.com/file/d/0B8a3rG93GTRedkhvbWc5Ujl4Unc/view?usp=sharing

после того как я переименованы следующие:

От: YourEntity + CoreDataClass.быстрый К: Ваше Здоровье.Свифт

и

От: YourEntity + CoreDataProperties.быстрый Кому: YourEntityCoreDataProperties.Свифт

затем он работает. Похоже, что " + " вызывает проблему.