Core Data with SwiftUI Tutorial: Getting Started | raywenderlich.com

In this Core Data with SwiftUI tutorial, you’ll learn to persist data in an app using @State, @Environment and @FetchRequest property wrappers.


This is a companion discussion topic for the original entry at https://www.raywenderlich.com/9335365-core-data-with-swiftui-tutorial-getting-started

There are bugs! Before adding any code new code to the project, Xcode generates all kinds of strange and potentially nasty messages when compiling.

The first line of code “ lazy var persistentContainer: NSPersistentContainer” generates a red fatal error


I appreciate you guys are working fast to produce tutorials after Apple pulled a swift one on the whole industry with iOS 13 Xcode 11 but could you review your code more thoroughly. Thank you

Hi @richardwau, I’m sorry to see you’re running into issues! Could you please share what you mean by “strange and potentially nasty messages when compiling”? The app appears to compile fine on Xcode 11.5, so let’s see if we can track down the issue you’re experiencing.

Hi Keegan,

thanks for responding. After reading the first part of the Apple tutorial Apple Developer Documentation , I figured out the error with the "lazy var persistentContainer
 " The RW Tutorial says “Now, add the following at the end of SceneDelegate”. But you really mean add it the class and not the file right? So I suggest more precision in the English.

FWIW, Apple make this declaration in the AppDelegate. I’m not sure if this makes a difference if any but I’ll go with the Apple way when I implement.

The compiler messages from Xcode 11.5 before I make any of the modifications are below. They look like they’re related to layout issues but it would be nice if they weren’t there. While I’m new to Swift and RW none of the other RW tutorials I’ve done have issues like this. These messages and the difference between the RW tutorial and Apple’s documentation erode confidence.

Thanks

Richard

2020-05-26 17:20:32.983008+1000 FaveFlicks[6798:2526252] [plugin] AddInstanceForFactory: No factory registered for id <CFUUID 0x600003df5d80> F8BB1C28-BAE8-11D6-9C31-00039315CD46

2020-05-26 17:20:41.049761+1000 FaveFlicks[6798:2526041] [LayoutConstraints] Unable to simultaneously satisfy constraints.

Probably at least one of the constraints in the following list is one you don’t want.

Try this:

(1) look at each constraint and try to figure out which you don’t expect;

(2) find the code that added the unwanted constraint or constraints and fix it.

(

“<NSLayoutConstraint:0x600001e01540 ‘assistantHeight’ TUISystemInputAssistantView:0x7f886be1a300.height == 44 (active)>”,

“<NSLayoutConstraint:0x600001e14d20 ‘assistantView.bottom’ TUISystemInputAssistantView:0x7f886be1a300.bottom == _UIKBCompatInputView:0x7f886bf5b0f0.top (active)>”,

“<NSLayoutConstraint:0x600001e14cd0 ‘assistantView.top’ V:|-(0)-[TUISystemInputAssistantView:0x7f886be1a300] (active, names: ‘|’:UIInputSetHostView:0x7f886bf65dc0 )>”,

“<NSLayoutConstraint:0x600001e0db30 ‘inputView.top’ V:|-(0)-[_UIKBCompatInputView:0x7f886bf5b0f0] (active, names: ‘|’:UIInputSetHostView:0x7f886bf65dc0 )>”

)

Will attempt to recover by breaking constraint

<NSLayoutConstraint:0x600001e14d20 ‘assistantView.bottom’ TUISystemInputAssistantView:0x7f886be1a300.bottom == _UIKBCompatInputView:0x7f886bf5b0f0.top (active)>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.

The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.

2020-05-26 17:23:24.158389+1000 FaveFlicks[6798:2529008] -[_UIRemoteKeyboards proxy]_block_invoke Failed to access remote service: Error Domain=NSCocoaErrorDomain Code=4099 “The connection to service on pid 6677 named com.apple.UIKit.KeyboardManagement.hosted was invalidated from this process.” UserInfo={NSDebugDescription=The connection to service on pid 6677 named com.apple.UIKit.KeyboardManagement.hosted was invalidated from this process.}

2020-05-26 17:23:24.173149+1000 FaveFlicks[6798:2526041] [Snapshotting] Snapshotting a view (0x7f886d840000, UIKeyboardImpl) that is not in a visible window requires afterScreenUpdates:YES.

2020-05-26 17:23:46.565002+1000 FaveFlicks[6798:2526041] [Snapshotting] Snapshotting a view (0x7f886c010e00, UIKeyboardImpl) that has not been rendered at least once requires afterScreenUpdates:YES.

Message from debugger: Terminated due to signal 9

Hi @richardwau, some very valid points, and I’m sorry for the issues you’ve experienced. I’m in agreement with leaving it in the AppDelegate as seen in Apple’s default implementation.

Thanks for the detailed tutorial! I’m familiar with Core Data but new to SwiftUI, so this was very helpful.

One thing I’d like to share:

All attributes on a Core Data entity are optional.

While this is true for the types used in this example, it isn’t always the case. For example, if you define a Float with Use Scalar Type enabled, the generated property will not be optional.

Hi @haslager, thank you for pointing out that overlooked exception!

Hi @keeganrush , thank you for this great tutorial! Im new to SwiftUI, so this was very helpful. But I have one issue, because I have a LoginView which I want to appear first and after the LoginView should appear the MovieList. Could you tell me please how to handle this in the SceneDelegate. Currently I have this code in my SceneDelegate:
“let context = persistentContainer.viewContext
let contentView = MovieList().environment(.managedObjectContext, context)”

Hi @denise124, glad you liked it! When you set MovieList as the contentView, in your SceneDelegate, as in the code you included, it becomes the first screen of the app. So, in your case, you should set LoginView as the contentView in your SceneDelegate. Then your LoginView can create and display the MovieList.

Oh okay, thank you very much @keeganrush! :+1:

Hi, i keep getting a program crash. The diagnostic logs show a getter failure

|0 com.apple.SwiftUI 0x00007fff2c8c915a FetchRequest.wrappedValue.getter + 410
1 com.raywenderlich.FaveFlicks 0x000000010432b933 MovieList.movies.getter + 291
2 MovieList.2.preview-thunk.dylib 0x0000000106364644 closure #1 in closure #1 in MovieList.__preview__body.getter + 196
3 MovieList.2.preview-thunk.dylib 0x000000010636477d partial apply for closure #1 in closure #1 in MovieList.__preview__body.getter + 13
4 com.apple.SwiftUI 0x00007fff2c65a283 List<>.init(content:) + 83
5 MovieList.2.preview-thunk.dylib 0x0000000106363d6d closure #1 in MovieList.__preview__body.getter + 429
6 MovieList.2.preview-thunk.dylib 0x000000010636436c partial apply for closure #1 in MovieList.__preview__body.getter + 12

In MovieList,swift, there are issues with Movies, ( that is the entity name in in FaveFlicks.xcdatamodeld) ie Use of undeclared type ‘Movies’. I have tried to do the codgen: Manual/None, saving and restarting the instance of FaveFlicks.xcodeproj, cleaning Build folder, all to no avail

Xcode 11.6, MacOS 10.15.6

Drowning in Core Data
Rob

oops, i did a little misleading. I changed the name from ‘Movies’ to ‘Movie’, midstream, then changed the diagnostic log., so my explanation is wrong. After changing to ‘Movie’, it still crashes. Sorry for the confusion

Rob

Hi,

previous entries for my complaint was using the Xcode preview. Using simulator worked. So, is simulator a requirement? That would be nice to know.

Good evening I’m new, in the meantime I would like to congratulate you on your tutorial which included swiftUI and CoreData, I found it very useful. I would like to know if you have in your catalog a text or a course that retraces the structure of “coreData by Tutotials” but not written for UIKIT but, only for swuiftUI. I recently started coding and saw Apple’s abandonment of UIKit I didn’t even look at it. I started immediately from SwiftUI, and now I would like to start comparing myself with CoreData, but the text I found in the catalog is of no help to me. Thank you in advance for the answer.

Hi @caflatlander, I’m sorry you had troubles but it’s great to see you made it through! I often have problems with SwiftUI previews in the latest version of Xcode, so when it fails, falling back to a simulator or real device is always a great idea.

Hi and welcome, @davidtradingonline! This is our only tutorial focused on Core Data in SwiftUI. UIKit will be around to stay for awhile before it’s eclipsed by SwiftUI, so if you’d like to learn more about Core Data, Core Data by Tutorials could be a great jumping off point!

Good afternoon, I have a problem managing the functioning of the relationships between entities in CoreData.
I have a table that virtualizes a client:

  1. denomination
  2. VAT number
  3. address
  4. telephone
  5. Agent ()
  6. Payments ()

point 5 () Agent should give the possibility to connect another entity that goes to connect the agent data:
a) agent name
b) agent address
c) VAT agent number

point 6 should also be linked to another entity that describes the collection methods of that customer:
I) payment description
II) number of payment installments
III) days of first installment payment 


I know this is an elementary subject, I am studying the “Beginning Core Data” lessons. In lesson 16 I see the same kind of relationship being created but I can’t reproduce it in any way.
Thanks a lot David.

Hi @davidtradingonline, you’re almost there: try take a look at Lesson 17, “Relationships” in Beginning Core Data.

Keegan you are great !! I was stuck and I could not understand how to go on, it was enough just to take a step to lesson 18 Thanks !!

Hi @keeganrush
I have a problem with the new CoreData system, the one without AppDelegate, I can’t understand how to make everything work fine. In particular, I believe that I am unable to run the new Persistence file. If I understand correctly, at this time the writing on CoreData happens here. i try to copy you the code as i wrote it, i don’t understand what i am wrong. THANKS

Persistence File →

import CoreData

struct PersistenceController {
static let shared = PersistenceController()

static var preview: PersistenceController = {
    let result = PersistenceController(inMemory: true)
    let viewContext = result.container.viewContext
    
    let cliente = Cliente(context: viewContext)
    cliente.id = ""
    cliente.denominazione = ""
    cliente.email = ""
    cliente.vatNumber = ""
    
    do {
        try viewContext.save()
    } catch {
        // Replace this implementation with code to handle the error appropriately.
        // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
        let nsError = error as NSError
        fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
    }
    return result
}()

let container: NSPersistentContainer

init(inMemory: Bool = false) {
    container = NSPersistentContainer(name: "Cliente")
    if inMemory {
        container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null")
    }
    container.loadPersistentStores(completionHandler: { (storeDescription, error) in
        if let error = error as NSError? {
            // Replace this implementation with code to handle the error appropriately.
            // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.

            /*
            Typical reasons for an error here include:
            * The parent directory does not exist, cannot be created, or disallows writing.
            * The persistent store is not accessible, due to permissions or data protection when the device is locked.
            * The device is out of space.
            * The store could not be migrated to the current model version.
            Check the error message to determine what the actual problem was.
            */
            fatalError("Unresolved error \(error), \(error.userInfo)")
        }
    })
}

}

1 Like