Xcode 8 genera subclases NSManagedObject rotas para iOS 10

Actualicé recientemente mi proyecto de aplicación para iOS en iOS 10. Ahora bash cambiar el Modelo de datos básicos de mi aplicación, pero las nuevas subclases NSManagedObject que genera Xcode están rotas. También intenté arreglar el manual de las subclases pero esto no funciona.

La versión mínima de herramientas para el Core Data Model está configurada en Xcode 7.0 y el lenguaje de generación de código está configurado en Swift.

Este es el código que genera 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) } 

Editar: Estos son los errores específicos que da 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 

Finalmente conseguí que los míos trabajaran. Aquí esta lo que hice. (Los vuelos son una de mis entidades)

Configuro el xcdatamodeld de la siguiente manera

enter image description here

Y luego la entidad como

enter image description here

Luego usé Editor -> Crear subclase NSManagedObject

Esto crea dos archivos para mi entidad de vuelos

Vuelos + CoreDataProperties.swift

Vuelos + CoreDataClass.swift

Cambié el nombre de Flights + CoreDataClass.swift a Flights.swift

Flights.swift es solo

 import Foundation import CoreData @objc(Flights) public class Flights: NSManagedObject { } 

Vuelos + CoreDataProperties.swift es

 import Foundation import CoreData extension Flights { @nonobjc public class func fetchRequest() -> NSFetchRequest { return NSFetchRequest(entityName: "Flights"); } @NSManaged public var ... } 

Esto parece funcionar para mí. No pude hacer que Codegen funcionara de ninguna otra manera, aunque probé muchas de las sugerencias que estaban por ahí.

También esto me hizo rascarme la cabeza por un tiempo y lo agregué como una ayuda. No olvides que con la nueva versión de Generics de FetchRequest puedes hacer esto

 let fetchRequest: NSFetchRequest = NSFetchRequest(entityName: "Flights") 

Creo que la razón por la que encontró esos errores después de generar los archivos de la subclase NSManagedObject puede estar relacionada con la opción Codegen que se seleccionó en el momento en que cambió su modelo de datos.

No creo que esto sea un error. Al menos no en Xcode 8.1 (8B62).

Encontré un problema similar y lo solucioné cambiando la opción Codegen a “Manual / None” y dejando la opción Module como “Global Namespace”. Luego generé mis archivos de subclase NSManagedObject. Sin embargo, dependiendo de su situación, es posible que ni siquiera necesite generar las subclases NSManagedObject.

A continuación hay más detalles sobre la entidad de las opciones de Codegen, mi revisión de la documentación de Apple, el foro de desarrolladores de Apple y las pruebas con mi propio proyecto.

Opción 1: “Definición de clase”

  • Piense en esto como la opción de “enchufar y jugar”

  • Use el editor de modelos para crear las entidades y los atributos asociados que desea que administre Core Data.

  • No use el generador de subclase NSMangagedObject. Xcode genera automáticamente los archivos necesarios (sin embargo, no aparecen en el navegador del proyecto).

  • Si genera los archivos NSManagedObject, Apple le informa que estos archivos no deben editarse en los comentarios del encabezado de dichos archivos. Si necesita editar estos archivos, entonces esta es una buena señal de que necesita usar otra opción de Codegen.

  • Deje las opciones de Clase predeterminadas para su entidad (Módulo = Espacio de nombre global y Codegen = Definición de clase)

  • Si necesita anular los métodos de NSManagedObject, puede crear una extensión utilizando el nombre en la opción Clase.

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

Opciones 2: “Manual / Ninguna”

  • Similar a la Opción 1, excepto que puede ver y editar los archivos de la subclase NSManagedObject.

  • Use el editor de modelos para crear las entidades y los atributos asociados que desea que administre Core Data.

  • Antes de usar el generador de subclase NSManagedObject, configure la opción Codgen en “Manual / None” para la entidad. La opción Módulo debe ser Espacio de nombre global.

  • Después de agregar / eliminar / actualizar un atributo, tiene dos opciones: (1) Actualizar manualmente los archivos NSManagedObject que se generaron para usted O (2) Usar nuevamente el generador de subclase NSManagedObject (esto solo actualizará el archivo Entity + CoreDataProperties.swift )

  • De nuevo, si necesita sobrescribir y los métodos de NSManagedObject, puede crear una extensión. La extensión debe crearse en el archivo Entity + CoreDataClass.swift y no en el archivo Entity + CoreDataProperties.swift (este archivo podría actualizarse debido a cambios en el editor de modelos).

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

Opción 3: “Categoría / Extensión”

  • Use esta opción si tiene propiedades personalizadas que no necesitan ser administradas por Core Data.

  • Use el editor de modelos para crear las entidades y los atributos asociados que desea que administre Core Data.

  • Asegúrese de que la opción Módulo está configurada en Módulo de producto actual y la opción Codegen está configurada en “Categoría / Extensión”.

  • Cree su propia subclase NSManagedObject con las propiedades que usted mismo administrará.

  • No use el generador de subclase NSMangagedObject. Xcode genera automáticamente los archivos necesarios (sin embargo, no aparecen en el navegador del proyecto).

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

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

  1. Para resolver este problema, elimine los datos derivados de la aplicación.

  2. Luego cambie el Módulo al Módulo de producto actual y también realice cambios en Codegen a Manual / None .

  3. Artículo de lista

Intente configurar CodeGen: Manual / None Module: Módulo de producto actual

Me funcionó bien cuando tuve el mismo problema.

enter image description here

Si tiene una aplicación heredada y desea seguir agregando clases de objetos gestionados manualmente

  1. Asegúrese de que su codegen del modelo de datos básicos esté configurado en Manual / None
  2. Seleccione su archivo de modelo de datos principal
  3. Crear subclase de objeto administrado

captura de pantalla del editor

Puedes probar estos pasos

  1. Seleccione el archivo .xcdatamodeld en Xocde Project Navigator
  2. En Data Modul Inspector , asegúrese de que Codegen : Manual / None
  3. Luego Edit -> Create NSManagedObject Subclass
  4. Limpiar producto y reconstruir

Es ese trabajo? Si no

Asegúrese de que toda la clase no tiene el mismo nombre con las entidades . Puedes encontrar estas clases en Fases de comstackción -> Comstackr fonts . Cambie el nombre de la clase o Entidades si duplicaron

O

Puede ejecutar este comando en su carpeta de proyecto para obtener más información de error

xcodebuild -verbose

Recibí este mensaje cuando tengo este problema

símbolo duplicado _OBJC_CLASS _ $ _ RandomList en:

xxxx / RandomList.o

xxxx / RandomList + CoreDataClass.o

RandomList.h y RandomList + CoreDataClass.h tienen un mismo símbolo al comstackr

Creo que por eso Xcode no te advirtió, pero el comstackdor lanzará un error

Espero que esto te ayudará

Elimine el tercer extracto de import porque está vacío.

Nota: No sé por qué sucede esto, pero supongo que es un error en Xcode 8. Simplemente elimínalo y funcionará bien.

En Xcode 8.2.1 , lo hice de la manera: (gracias por Daniel Chepenko )

enter image description here

Pero Xcode 8.2.1 agregará un estúpido . en los archivos generados:

enter image description here

Solo borre el . y correrá bien

Acabo de tener un problema donde acabo de agregar una entidad Person en mi modelo a la plantilla Core Data. Luego generé la subclase NSManagedObject para eso y no se comstackrá, lo que me da un error de enlazador. Resulta que se supone que debo cambiar la opción Codegen a Manual / None para que funcione (ver parte inferior derecha de la imagen). enter image description here

Creo que es un problema de xcode, donde xcode genera una syntax incorrecta para la clase de categoría de datos básicos. Estoy creando un nsmanageobjectsubclass para una entidad AgentDetails Está creando las siguientes clases

Aquí xcode crea una estructura de código incorrecta en AgentDetails+CoreDataClass.h AgentDetails+CoreDataClass.m . Esos tienen una estructura de código como:

enter image description here

Y

enter image description here

Por lo tanto, tiene un problema de interfaz duplicado ya que AgentDetails.h tiene la misma interfaz.

Ahora para arreglar esto, debes cambiar el código en AgentDetails+CoreDataClass.h

enter image description here

y AgentDetails+CoreDataClass.m gusta esto:

enter image description here

En Data Model Inspector seleccione Current Product Module en ‘Module’ y Manual / None en ‘Codegen’. (Esto le permite editar archivos de subclase y regenerar CoreDataProperties.swift cuando modifica sus atributos bajo la misma entidad).

enter image description here

A continuación, puede elegir Crear NSManagedObjectSubclass en el menú Editor. Xcode creará 2 archivos para usted YourEntity + CoreDataClass.swift y YourEntity + CoreDataProperties.swift. Observe que si no tiene el último Xcode (8.2.1), las propiedades opcionales / no opcionales que configure en su Model Inspector no se mostrarán correctamente. Puede editar en su archivo YourEntity + CoreDataProperties.swift.

Xcode 8.1 parece estar generando la clase de modelo internamente. Simplemente borre las 2 clases creadas y aún podrá usar las entidades en su código.

Aquí está el mensaje de error que estaba recibiendo

 :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' :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 

Además, si agrega la subclase NSManagedObject usted mismo, no olvide seguir el siguiente paso: Vaya a ‘.xcdatamodeld’ -> Elija la entidad -> Mostrar el inspector del modelo de datos -> Codegen -> Elija ‘Manual / None’

Esto funcionó para mí.

Encontré esta publicación de David Atkinson, que es útil de alguna manera. Si genero el código de la manera en que David describió. Acabo de obtener el código con algunos errores de syntax y, si corrijo los errores, todo funciona igual que antes. No faltan archivos que comienzan con ‘.’ nunca más.

Los errores de syntax que tengo que corregir son – la importación innecesaria – y algunas propiedades públicas que no están destinadas a ser públicas en mi código

Estoy ejecutando la última versión de Xcode 8.1 beta (8T47).

De acuerdo con el registro de errores (ver a continuación), se crean dos copias de los archivos autogenerados. Se coloca una copia en su carpeta de proyecto Xcode (la visible en su directorio en la barra de herramientas de la izquierda de Xcode), y se crea una segunda copia en su carpeta DerivedData para su proyecto:

 /Users//Library/Developer/Xcode/DerivedData/-axhtnodotznxnrenefflktnxfeal/Build/Intermediates/.build/Debug-iphonesimulator/.build/DerivedSources/CoreDataGenerated//+CoreDataProperties.swift /Users//Library/Developer/Xcode/DerivedData/-axhtnodotznxnrenefflktnxfeal/Build/Intermediates/.build/Debug-iphonesimulator/.build/DerivedSources/CoreDataGenerated//+CoreDataClass.swift 

Eliminar las copias en el directorio de proyectos de Xcode solucionará todos los problemas, pero no tiene ningún sentido ya que ya no puede editar estos archivos …

No diría que es una solución, sino solo una forma a medias para que el proyecto se construya. Esperemos que este error se aborde pronto.

Registro de errores

Para mí, creé clases CocoaTouch subclases de NSManagedObject de NSManagedObject manual. Configuré el módulo como Módulo de Producto Actual y Codegen como Categoría / Extensión y funciona bien.

En mi caso particular, agregué CoreData a un proyecto existente que ya tenía una clase Model con el mismo nombre que mi entidad. La eliminación de la antigua clase de modelo solucionó el problema, ya que su tipo colisionaba con la nueva clase de entidad de CoreData.

Lo que debe hacer es configurar el CodeGen en Categoría / Extensión antes de ejecutar las subclases Create NSManagedObject.

Tengo una Entidad de Vuelos y esta configuración en el Inspector de Modelo de Datos funcionó para mí:

  1. Establezca el Nombre en nada (verá un texto atenuado de “NSManagedObject”). El valor predeterminado se escribirá como “Vuelos”, simplemente quítelo.

  2. No hay nada en el módulo. El “espacio de nombre global” en gris es lo que verá.

  3. Codegen a Manual / Ninguno.

  4. Luego, vaya a Editor -> Crear subclase NSManagedObject para crear los archivos rápidos

  5. Cambie el nombre de Flights + CoreDataClass.swift a simplemente Flights.swift

Aquí está el enlace a la captura de pantalla (por alguna razón, imgur la rechazó :() https://drive.google.com/file/d/0B8a3rG93GTRedkhvbWc5Ujl4Unc/view?usp=sharing

Después de renombrar lo siguiente:

De: YourEntity + CoreDataClass.swift a: YourEntity.swift

y

De: YourEntity + CoreDataProperties.swift a: YourEntityCoreDataProperties.swift

entonces funciona Parece que “+” está causando el problema.