One-to-many relationships with @FetchRequest and SwiftUI – Core Data SwiftUI Tutorial 7/7

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] core data allows us to link entities together using relationships and we request an object we'll get those relationships provided to us automatically however this is an area where core data really starts to show its age as you'll see we're going to make a custom ns manage object subclass we can edit to add a few wrappers to make the whole thing play nicely with 50y now to demonstrate this we're going to work with two entities one's attract candy bars and mother track the countries where those candy bars come from and they have a relationship between them now relationships come in four different types first you have a one to one where one object in this entity has another object over here matching it exactly one each time in our example it means that one candy bar will first have been introduced in one country which is true but that one country can only ever have introduced one candy bar which is a bit iffy so one to one one candy induced in one country one country only ever has one candy bar and produced there another option is one to many in our example it would mean that one candy bar can be introduced in many countries at the same time but those countries still only get to have one candy bar uh introduced there then we have many to one which is that flipping around all right come on get a treat flipping around the other example many to one what this means is come on dogs what this means is that uh we could have many candy bars all introduced in a single country right so this kind this candy bar here was first introduced in this is this place here for example and that each country can therefore have introduced many types of candy and finally we have many to many where there are many candy bars here in many countries here and each candy bar could have introduced in many countries and each country couldn't introduce many candy bars now all of those are useful at different times in your code but in this example i think the many-to-one relationship makes the most sense to be able to say that each type of candy was first introduced in a particular country invented in one particular country hello i do see you i know chocolate i know you don't get chocolate your dog each candy bar is first invented in one place but each country can invent multiple candy bars which makes sense i think anyway with that in mind go ahead and open up your data model and then add some entities here so we have two entities one for candy bars and one for countries um the first one i'll call candy second one i'll call country and then for candy i'll give this thing a single attribute which is name the name of the candy and that's going to be a string then for country i'm going to add two strings here we'll say we have a uh full name and a short name uh both of which will be strings so string and string i do see you down there i am conscious of you being very hungry dogs who never get fed come on that's it though it's your last treat one one stretch stretch good dog hold on okay so we've got our candy in our country right here and this makes sense it's a good layout because um yes some uh types of candy have the same name uh like smarties for example in the us and uk mean different things um countries they're unique right no two countries are the same name that'd be confusing right so we're going to add a constraint for the short name of our country so you want to go ahead and bring up the data model inspector i do see you doc i do see you're a good dog and then select country well don't lick me and then um go ahead and with country selected go ahead and press plus four constraints here and rename this thing to b come on you can do it there we go rename this thing to be short name so we're saying the short name of each country must be unique that's how it's done now before we're done here we're going to tell core data there's a one to many relationship between candy and country or minute to one beneficially looking one for me this way main to one this way when you look at it and to do that you want to select country here and then look under the relationships area for this plus button and then press plus inside there call this thing candy and change destination to be candy so it's pointing to there and now over in the data model inspector change type to be to many so one country has many candy that's what we're saying here now select candy and then add a relationship here too and we'll say this thing is called origin where the candy is from its destination should be country as inverse the opposite will be candy so it understands that country candy the same as candy origin they're both the same relationship between these two and that completes our entities right so the next step is to go ahead and look at the xcode code we'd get from this so press command s to save your quality model select both your entities candy and country then change code gen from class definition to be manual none and then go to editor create ns manage object subclass press next and press next and then put it into the correct location so that'll be in here and in here keep your code neatly organized boom so you're gonna get a whole bunch of code now and um there are four now because there's two entities candy and country uh it is complaining loudly at me cool there we go uh so candy and country at the same time with each one having properties and properties here right here and it should be pretty much what you expected you're not getting any more treats from me um but you will notice that the country's properties this is more complicated here because there's all sorts of code down here to add candy uh to our objects right it understands it's more complex now and there's also a candy thing up here now previously we looked at how to clean up cordless optionals using these ns coming from scratch then these ns manage object subclasses that's what we looked at doing but here there's a bonus complexity which is that this thing has a candy property which is an optional ns set we haven't used ns sets before because they're the older objective c data type they're the equivalent of swift's modern set but we can't use ns set with for each it doesn't work can't use that and so to fix this we're going to modify the files xcode made for us and it's convenience wrappers to make swifty y work better for the candy class that's easy right we've got our name here so we'll just say there is a public var unwrapped name thank you dog which is a string and that will be our name nilco letting down to unknown candy that's the candy one done for the country one this is more complex because we want to have the wrapped short name and the wrapped full name so that's public var wrapped short name a string that short name capital n nil coalescing unknown country and then the same thing for wrapped full name so full name here and then full name here however things are more complex when it comes to this candy property because an ns set and that could contain anything at all it doesn't say it's ns set of candy now we know it is but core data has not said that because ns set does not work that way and so to get anything useful from this for a swifty y layout will convert this thing from an ns set to a set of candy that is a swift native type the set which knows it's got candy inside once we have that we can convert it to be an array so 4h can loop over individual values from there we'll also sort the array so a hand has a candy bars in a sensible order now swift actually lets us put some other steps into one because sorting a set automatically returns an array because otherwise it wouldn't be sorted anymore you know i'm sorting it just give you another unsorted set right however sorting the array is hardly you might think because this is an array of custom types so we can't just use sorted and hope for the best instead we're going to provide a custom closure to say how to sort it so we're going to say public var candy array is an array of candy and so we first get our set equals our current candy as a set of candy nil coalescing to an empty array oh andrew said sorry so we're trying here a conditional typecast which means this ns set is actually going to be a set of candy try and convert from ns set to set of candy and if that works brilliant use that if it fails this whole thing this whole conditional typecast will return nil it'll fail the test and therefore get back an empty set instead and now we can return that set sorted and we're gonna say dollar zero dot rap name is less than dollar one dot rap name like that now it's rap name please it's thinking uh now what i call it in candy i called it unwrapped name sorry rap name my mistake okay so we've converted this pretty hideous optional ns set with no idea of what's inside it into a sensible this is an array of candy and it's sorted in a sensible way so that's really nice and that completes our core editor classes so now we can write some shift ui code to make all this work over in content view we already have our manage object context let's hide in these bars you can see what's going on more easily we already have our manage object context right here we're going to add to that a fetch request up here so at fetch request using sort descriptors of an empty array no predicate var countries will be a fetched results of country now we haven't had to specify anything about our fetch request to say what the relationships are right core data understands that country and candy is linked together it understands how it's going to work it's not going to complain here in terms of making us be exact in terms of what we ask for it will always work it'll pull out the country correctly and plot the candy bars for it without any further questions which is really nice so next up the body of the view down here we're going to use a list with two for each views inside it one to make a section for each country and then one to make a candy inside each country so we're gonna have uh that list with the countries and then candy bars inside the countries and we'll then we'll have below the list in like a v stack a button to add some sample data so i'll say there's a v stack here with a list inside it and first up we'll have for each one of our countries with id of backslash dot self give me a country in so for each one of our countries give me a section with a title and i'll use our country wrapped full name like that and inside the section we'll say another for each for each country.candy array with again id of backslash dot self give me one candy in text candy dot wrapped name so show all the countries and all the candies for those countries there now after the list down here we'll do button add examples so we have some sample layers to work with and he'll make a bunch of candy we'll say let candy one be a candy or the context of our managed object context candy1.name is a mars the classic mars bar candy1.origin this is going to be a country object again um manage object context remember it's a separate object uh candy one origin dot short name is capital n is the uk because it's made in the uk first and then candy one origin question mark dot full name is united kingdom i'm going to copy and paste a few times here otherwise be a lot of typing so copy and paste candy 1 to be two three and four so we've got four kinds of candy let's change these nums a little bit so candy two candy two candy two candy two candy two candy three candy three three three three and then four four four four four so candy two we'll say is the kitkat that was first made in the uk so that's all the same candy three will say is a twix bar that was first made in the uk we do like chocolate here a lot and then candy 4 is a toblerone that was made in switzerland that's the exception here switzerland and the short name of switzerland is ch because they are the helvetican republic or confederation sorry anyway four candy bars here with their correct origins and a dog you hear the word candy no try mock.save all right you've been patient come on this is it though honestly i said that before i'm sure at least twice um come on that's it good dogs you are good dogs now clear off now please make sure you run this code give it a try um it just worked brilliantly well uh i'll press command r to build around the code now hope to have made no comedy typos along the way i'll press add examples and we should see bang switzerland has toblerone uk has kitkat mars and twix and if you don't see that if you see an error in your debug log or similar if nothing happens there's a good chance you have not got the merge policy in place in our data controller you've got to set a merge policy here remember i made sure all my countries have a unique name that was constraintly added into the model we were working earlier i said the model here the country had a constraint over here on short name the short name has to be unique so even though we make lots of the objects inside our content view we make multiple uk's here it'll only actually create one of them behind the scenes because the short name uk must be unique and so we'll understand that mars kitkat and twix belong to the same piece of data so the result is all our data is beautifully split up by country and then sorted toblerone kitkat mars and twix all alphabetical uh and that's all by pressing the examples button it's doing most of the work for us in fact all the heavy lifting is being done by core data and a little bit of work from us when we had to do the uh wrapper stuff for our our candy array here but that's just because ns set's being used and we want to get rid of that sort of old objective c style of code and have a nice network swift ui anyway the result i think is quite brilliant and it shows the power of coordinator and hungry dogs hungry hungry dogs a good dog yeah you are and you're quite good too
Info
Channel: Paul Hudson
Views: 494
Rating: undefined out of 5
Keywords: xcode, swift, swiftui, ui, ios, programming, tutorial, example, project, code, uikit
Id: 0QGt0THnlwU
Channel Id: undefined
Length: 17min 4sec (1024 seconds)
Published: Sat Nov 27 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.