I am using a .playground file and I can't seem to add my CoreML model to it. I drag it into the Resources folder and this is my code:
func predict(image: CGImage) {
let model = try! VNCoreMLModel(for: Inceptionv3().model)
let request = VNCoreMLRequest(model: model, completionHandler: results)
let handler = VNSequenceRequestHandler()
try! handler.perform([request], on: image)
}
However, I get the error saying:
Use of Undeclared Type Inceptionv3
Can someone please help me out?
The compiler raises this error, because it cannot find a declaration of the class Inceptionv3, that you try to instantiate an object of.
This class is automatically created for you as long as you have a regular Xcode project. If you want to work with it inside a Swift playground, you will need to add this file manually:
First, create a regular Xcode project (an iOS app for example) and integrate your mlmodel there. Xcode will then generate an interface for that model automatically. These are exactly the files that are missing in your project and contain the definition of the Inceptionv3 class.
The same problem has been asked and answered here. There you can also find an image showing how to find the automatically generated classes.
Related
I am creating a playground in Xcode and I do not understand why the "Sources" files cannot talk to each other. I am using SpriteKit which means it is ideal to have one swift file per scene, in my case I have one scene per level. I cannot use a quick workaround and add everything into one massive file... there has to be a better way. Both classes for the two swift files are public. You should be able to access them. Thanks!
I get this error when I try to an object from one class, LevelScene, in the other class TitleScene.
After this
let levelScene = LevelScene(fileNamed: "LevelScene")
This happens
Cannot find 'LevelScene' in scope
I am aware of this post. This solution still does not work for me.
Xcode playgrounds can't access swift files in Sources folder
I am on Xcode 12.4.
Thanks!
You need to declare all your classes/struct in each file as public.
So, if you have defined a struct like this in a file:
struct Node {
var id: Int
}
You need to declare is like so:
public struct Node {
var id: Int
}
Then your code should work. You can use a struct from one file in another file as long as you declare them as public. Similar concept goes for any functions/methods inside those structs/classes. Even with this solution, you may find Xcode 12.4 complaining about not finding the type in scope. That, I believe, is a known bug. I have the same bug on my Xcode 12.4. I am able to build and run the code even with that error.
I'm trying to test CoreData in my swift package as SPM now supports bundled resources including .xcdatamodel, my tests can't seem to locate my NSManagedObjects though. What are the steps to unit test core data from the tests?
I'm getting this error when i try to create a NSManagedObject from a test:
+entityForName: could not locate an entity named 'StriveUser' in this model. (NSInternalInconsistencyException)
I've triple checked the naming and it's all correct.
I'm creating the object like this from my tests:
let object = NSEntityDescription.insertNewObject(forEntityName: "StriveUser", into: self.inMemoryStore.context)
And here's my code for locating the .xcdatamodel:
fileprivate var managedObjectModel: NSManagedObjectModel = {
guard let managedObjectModel = NSManagedObjectModel.mergedModel(from: [Bundle.main]) else {
preconditionFailure("Error getting ManagedObjectModel")
}
return managedObjectModel
}()
final class InMemoryStore {
let context: NSManagedObjectContext
init() {
let description = NSPersistentStoreDescription()
description.type = NSInMemoryStoreType
description.shouldAddStoreAsynchronously = false
let container = NSPersistentContainer(name: Constants.modelName, managedObjectModel: managedObjectModel)
container.persistentStoreDescriptions = [description]
container.loadPersistentStores {_, error in
if let error = error {
fatalError("Failed to load store: \(error.localizedDescription)")
}
}
self.context = container.viewContext
}
}
If you declare a Swift tools version of 5.3 or later in your package manifest, you can bundle resources with your source code as Swift packages. For example, Swift packages can contain asset catalogs, storyboards, and so on.
When resources are defined, a new static Bundle reference is created for the package. This can be accessed using Bundle.module.
So for your ManagedObjectModel you will need update the bundle reference. A good way of using this is to have an accessor in your package that will return the model.
For additional information, you can check out Apple's developer documentation Bundling Resources with a Swift Package.
I ran into a similar issue, where my app would crash with "YourManagedObject not found" errors any time I tried to do anything with my core data models.
This started happening as soon as I moved my core data dependency from cocoapods to swift package manager.
But here was my solution:
add #objc(ManagedObjectName) to all of my NSManagedObject classes
in the core data model editor, in the Data model inspector, delete Current Project Module and use the default for the Module configuration.
As the above answers are saying, make sure to use Bundle.module instead of Bundle.main when loading your NSManagedObjectModel.
I rewrote our core data stack to use NSPersistentStore instead of manually setting everything up (NSPersistentStoreCoordinator, NSManagedObjectContext, etc...) as per WWDC 2018 core data best practices
A few things to note:
The problem wasn't because of the wrong bundle, I had already applied that change when migrating over to SPM. For some reason the app just couldn't find any of my NSManagedObject classes at runtime.
Try #1 and #2 before you try #4. I have no idea if #4 helped with this issue or not as the app stopped crashing when I removed Current Project Module. It definitely cleaned up a lot of ugly legacy code though.
I built a new bare-bones Swift Package to demonstrate the error that seems to be a cause of these issues, as of Xcode Version 13.3.1 (13E500a)
No NSEntityDescriptions in any model claim the NSManagedObject subclass 'TestModel.EntityMO' so +entity is confused. Have you loaded your NSManagedObjectModel yet ?
Breaking just after the model was loaded, I could see the entity existed:
(lldb) po model
(<NSManagedObjectModel: 0x6000015f8d70>) isEditable 1, entities {
Entity = "(<NSEntityDescription: 0x6000001c4b00>) name Entity, managedObjectClassName TestModel_TestModel.EntityMO,
<snip>
The managedObjectClassName seems to be the problem. It's the result of using Current Product Module in the class definition within the model, which appears to be concatenating the package top-level name and the containing folder in Sources. If I replace it with a hard-coded module of TestModel, then the error goes away and the test passes. Not ideal, but it worked in my case.
Xcode support for Core Data in swift packages seems to be a work-in-progress, as the editor still does not load correctly for .xcdatamodeld files. Just creating the test model had to be done in another project and moved to the package since I couldn't add an entity to an empty model file.
For reference, I'll also include my model initialization, which is very basic, but I believe reasonable relative to Apple guidelines. At the very least, it demonstrates that issues can exist beyond Bundle.module usage.
public struct TestModel {
internal static let modelURL = Bundle.module.url(forResource: "Model", withExtension: "momd")!
public static func persistentContainer() -> NSPersistentContainer {
let model = NSManagedObjectModel(contentsOf: modelURL)!
let description = NSPersistentStoreDescription()
description.type = NSInMemoryStoreType
let container = NSPersistentContainer(name: "Test", managedObjectModel: model)
container.persistentStoreDescriptions = [description]
container.loadPersistentStores { storeDescription, error in
guard error == nil else {
fatalError("Could not load persistent stores. \(error!)")
}
}
return container
}
}
I am using a .playground file and I can't seem to add my CoreML model to it. I drag it into the Resources folder and this is my code:
func predict(image: CGImage) {
let model = try! VNCoreMLModel(for: Inceptionv3().model)
let request = VNCoreMLRequest(model: model, completionHandler: results)
let handler = VNSequenceRequestHandler()
try! handler.perform([request], on: image)
}
However, I get the error saying:
Use of Undeclared Type Inceptionv3
Can someone please help me out?
The compiler raises this error, because it cannot find a declaration of the class Inceptionv3, that you try to instantiate an object of.
This class is automatically created for you as long as you have a regular Xcode project. If you want to work with it inside a Swift playground, you will need to add this file manually:
First, create a regular Xcode project (an iOS app for example) and integrate your mlmodel there. Xcode will then generate an interface for that model automatically. These are exactly the files that are missing in your project and contain the definition of the Inceptionv3 class.
The same problem has been asked and answered here. There you can also find an image showing how to find the automatically generated classes.
I upgraded a project I am working on to Swift 4.0. After doing so I realized this was not the best idea. I've fixed all bugs but one and can't figure it out. I have installed RealmSwift in my project and am getting the following error in one of the Realm files.
ERROR: Cannot call value of non-function type 'ThreadConfined.Type'
public init(to threadConfined: Confined) {
let bridged = (threadConfined as! AssistedObjectiveCBridgeable).bridged
swiftMetadata = bridged.metadata
type = type(of: threadConfined). ****ERROR CALLED ON THIS LINE****
objectiveCReference = RLMThreadSafeReference(threadConfined: bridged.objectiveCValue as! RLMThreadConfined)
}
Lesson learned about upgrading too soon. I was hoping someone could give me a hand so I can start developing again. Any thoughts?
Realm's master branch now contains support for Swift 4 and beta 1 of Xcode 9 (#5006). Using a build of Realm Swift from source should get you up and running.
I noticed that even though I was building from source (using CocoaPods), this issue was happening for me as well.
To solve it, two lines need to be removed (as seen in the file in #jonthornham's comment):
private let type: ThreadConfined.Type
and:
type = type(of:threadConfined)
Note: This is a different question than importing generic swift files (which can be done using the Sources folder).
I have a playground with 2 pages and I would like to use a protocol defined in the first page in the second page. I'll use an example of JSON conversion.
JSON.xcplaygroundpage
import Foundation
protocol JSONConvertible {
func jsonValue() -> String
}
JSONArray.xcplaygroundpage
import Foundation
//Undeclared type JSONConvertible
extension Array : JSONConvertible {
}
I have tried the following imports:
import MyPlayground
import MyPlayground.JSON
import JSON
import JSON.Contents (in finder the file name is actually Contents.swift)
I have also tried adding JSON.xcplaygroundpage into the Source folder of JSONArray as well as the Resources folder.
Note: I realize that I could put the protocol definition in a separate JSON.swift and include that in my project Sources folder. That doesn't really answer my question.
This is working in Xcode 8.3.3.
For code common to multiple pages, put it in separate files under top-level Sources group. Be sure to have proper Swift access control keywords in the right places.
Note from http://help.apple.com/xcode/mac/8.2/#/devfa5bea3af:
...the auxiliary Swift source file must export it using the public keyword. This includes classes, methods, functions, variables, and protocols.
Common.swift:
public class DoIExist { public init(){ print("Woot!")} }
Then you can reference it in all of the other pages. Like this:
Page2:
//: [Previous](#previous)
let d = DoIExist()
//: [Next](#next)
You can see that it works because of the console output ("Woot!") and the view results gutter.
To achieve this, I followed the directions at the Apple Xcode documentation about Playgrounds. When Apple inevitably moves those docs and does not provide a forwarding link, read on for how I found it.
I searched for the clues found in the link in cocoapriest's answer: "ios recipes Playground Help Add Auxilliary Code to a Playground". This leads to a document Apple is currently calling "Xcode Help" in a chapter titled "Use playgrounds" in a section titled "Add auxiliary code to a playground".
Just got this to work with this instruction by Apple: https://developer.apple.com/library/ios/recipes/Playground_Help/Chapters/AddAuxilliaryCodetoaPlayground.html
Make sure to declare your classes are public. Also, I had to re-start the Xcode to take the effect.