Подтвердить что ты не робот

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

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

Минимальная версия инструментов для Core Data Model установлена ​​на 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
4b9b3361

Ответ 1

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

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

введите описание изображения здесь

И затем объект как

введите описание изображения здесь

Затем я использовал Editor → Create NSManagedObject Subclass

Это создает два файла для моего объекта полета

Авиабилеты + CoreDataProperties.swift

Авиабилеты + CoreDataClass.swift

Я переименовал рейсы + CoreDataClass.swift в Flight.swift

Авиабилеты .swift просто

import Foundation
import CoreData

@objc(Flights)
public class Flights: NSManagedObject {

}

Полеты + CoreDataProperties.swift

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")

Ответ 2

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

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

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

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

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

  • Подумайте об этом как о опции "plug and play"

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

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

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

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

  • Если вам необходимо переопределить методы NSManagedObject, вы можете создайте расширение с помощью параметра "Имя под классом".

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

Опции 2: "Руководство/Нет"

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

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

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

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

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

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

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

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

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

  • Убедитесь, что для параметра "Модуль" установлено значение "Текущий модуль продукта" и Параметр 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 }

Ответ 3

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

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

  • Элемент списка

Ответ 4

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

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

введите описание изображения здесь

Ответ 5

Вы можете попробовать выполнить следующие действия.

  • Выберите файл .xcdatamodeld в Навигаторе проектов Xocde
  • В Data Modul Inspector убедитесь, что Codegen: Ручной/Нет
  • Затем Изменить Создать подкласс NSManagedObject
  • Очистить продукт и перестроить

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

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

или

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

xcodebuild -verbose

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

дублировать символ _OBJC_CLASS _ $_ RandomList в:

xxxx/RandomList.o

хххх/RandomList + CoreDataClass.o

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

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

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

Ответ 6

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

  • Убедитесь, что для вашей основной модели данных в кодеге установлено значение Ручное/Нет
  • Выберите файл основной модели данных
  • Создание подкласса управляемого объекта

скриншот редактора

Ответ 7

Удалить третий оператор import, потому что он пуст.

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

Ответ 8

На Xcode 8.2.1 я сделал так: (спасибо за Даниеля Чепенко)

enter image description here

Но Xcode 8.2.1 добавит глупость . в сгенерированные файлы:

enter image description here

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

Ответ 9

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

Ответ 10

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

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

введите описание изображения здесь

И

введите описание изображения здесь

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

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

введите описание изображения здесь

и AgentDetails+CoreDataClass.m следующим образом:

введите описание изображения здесь

Ответ 11

В Data Model Inspector выберите "Текущий модуль продукта" в разделе "Модуль" и "Ручной/Нет" в разделе "Кодекен". (Это позволяет редактировать файлы подкласса и регенерировать CoreDataProperties.swift, когда вы изменяете свои атрибуты под одним и тем же объектом.)

введите описание изображения здесь

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

Ответ 12

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

Ответ 13

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

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

Ответ 14

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

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

Ответ 15

Я запускаю последнюю версию бета-версии 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 устранит все проблемы, но окажется бессмысленным, поскольку вы больше не можете редактировать эти файлы...

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

Журнал ошибок

Ответ 16

Для меня я создал классы CocoaTouch путем подкласса NSManagedObject вручную. Я установил модуль как Current Product Module и Codegen как Category/Extension, и он работает хорошо.

Ответ 17

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

Ответ 18

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

Я наткнулся на эту самую проблему, и, проведя быстрое исследование, я смог обнаружить, что:

  • До Xcode 7 поведение по умолчанию для сущности Core Data заключалось в том, что разработчику приходилось вручную создавать и поддерживать изменения соответствующих подклассов NSManagedObject. (Это можно и можно сделать, используя меню редактора, выбрав опцию "Создать подкласс NSManagedObject...").

  • Начиная с Xcode 8, Apple включила новый параметр прямо в инспектор модели данных с именем Codegen для управления и поддержки подклассов NSManagedObject. Значением по умолчанию для этого параметра является "Определение класса", которое сообщает XCode генерировать подклассы NSManagedObject на основе наших определенных объектов во время компиляции и помещать их в папку производных данных.

Наличие в проекте наших подклассов NSManagedObject + те, которые Xcode генерирует автоматически, приводят нас к реальной причине ошибки времени компиляции "Несколько команд создают...", поскольку теперь у нас есть дублированные модели управляемых объектов !!!

Решение тогда состоит в том, чтобы использовать то или другое, а не оба! Я лично предпочитаю, чтобы мои модели управляемых объектов были включены в проект, поэтому я изменил настройку "Codegen" на "Manual/None". Если вы не добавляете логику к моделям, держу пари, вы можете отказаться, удалив модели управляемых объектов вашего проекта, и позволить XCode делать свое дело на основе значения "Определение класса" для упомянутой настройки. Это правильный способ справиться с этой проблемой.

Вы можете найти отличную статью, объясняющую все это подробно здесь:

https://medium.com/@kahseng.lee123/core-data-codegen-explained-462c30341041

Ответ 19

Я решил это как пример, приведенный ниже

Создать CurrentcyPair.xcdatamodeld

выберите CurrentcyPair.xcdatamodeld и выберите Default → Entity (CurrencyPair), переименуйте класс в (.ManagedCurrencyPair)

Выберите Entity и откройте инспектора. Установить код поколения в модели данных как Ручной/Нет

enter image description here

enter image description here

Ответ 20

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

Ответ 21

У меня есть объект "Полеты", и эти настройки в Data Model Inspector работали для меня:

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

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

  • Codegen to Manual/None.

  • Затем нажмите "Редактор" → Создать подкласс NSManagedObject для создания быстрых файлов

  • Переименуйте полеты + CoreDataClass.swift только на рейсы .swift

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

Ответ 22

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

От: YourEntity + CoreDataClass.swift To: YourEntity.swift

и

От: YourEntity + CoreDataProperties.swift To: YourEntityCoreDataProperties.swift

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