Developing iOS 11 Apps with Swift - 14. Persistence and Documents Demo

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
Stanford University all right well welcome to lecture number 14 of stanford cs193p fall of 2017 18 so I'm going to finish off the thing we had about the documents last time I was hoping to have finished that last time so we're kind of rushed for time this time especially since we're gonna get kicked out again for a midterm right after and then I'm gonna launch into a long demo that's gonna basically demonstrate all of the stuff we talked about on Monday all right so we did all that stuff on Monday so that we could easily take whatever our document based app is and store it in a document okay we went all the way through having UI document write things out to the file system now we're gonna add a really cool layer of UI in the front of that so that users can pick the documents they want rename them move them around all that right inside your app okay and the UI for this as you can see the screen shot up looks a lot like the files app in iOS 11 in fact the files app in iOS 11 is probably just a very thin layer on top of this UI or this API the UI document browser view controller okay so how does this thing work this view controller well the most important thing to understand is that it's just a view controller but it's always the root view controller of your application so in other words in your storyboard it's always got the little arrow that points to it and when you run your app it's gonna be the view controller users see first then they'll pick their whatever document they want and then your UI will take over okay your view controller will come up in front of this one do whatever it does to show your document alright so that's the fundamental architecture of this thing and one thing that's important to tell this little document browser view controller is what types of files you open and you do that in your project settings so if you go to project settings underneath the info tab you've got to select your target not the project but the target go to the info tab and then inside there there's a little section called document types well that's the types of documents you open and you just fill out this you can have multiple types and you fill out this little form that one and here for example I've shown how to have JSON files be a kind of file that you open okay and it's pretty straightforward they're the little things at the bottom they're the bundle type and the handler rank or basically just saying well is this like a primary type of file that you open are you the owner of this type of file or is it just some other type that you can that you know how to open et cetera okay now you can have your own document type for example for emoji art I'm not going to get to it today because of time constraints but emoji art really wants to have its own document type okay dot emoji art or something like that and you set that up in the section right below the document types called exported UTIs UTI stands for universal type and identifier and you can invent your own UTI as long as it's a nice unique name like here I've used the name edu da stanford cs193p dot emoji art that's very likely to be a unique type identifier and i just have to specify a couple of things most notably at the bottom there the file name extension that goes with an emoji art I picked emoji art dot dot emoji art okay and then once you set this up you can go back up to the document types one at the top and add this as a document type that you open just like that and yeah I explained the UTI there okay now we you know from the start of this class we always pick single view app as the type of app that we open them but we are actually for document based apps we're going to use an Xcode template it doesn't really give us much in that template but it gives us enough that it's worth doing so if you're going to do a document based app I recommend going back and creating a new app a new project using this as the template and in fact I'm going to do that in the demo even though we're you know 80% of the way through emoji art I'm still gonna go back and create a new emoji art with this and then just move my files over because I want the things that come with the template and let's talk about what's in that template one thing is that it stubs out that document types okay it doesn't do JSON files it does image files but you can change it to JSON files or add more types it also puts an entry in your info.plist which is very important called supports document browser and that's basically just saying that the documents that are stored inside your app sandbox are like real documents that people would want to open with like the files app or something like that so that's an important entry to put in your info.plist we're actually gonna put that in in the demo manually just to emphasize it it has one method in app delegate you know app delegates that file that we're always moving out of the way into supporting files so it has one method in there that allows other apps like the files app to ask your app to open your documents okay and it's a very simple old method we're not really going to look at it today but this template does throw that in there for you it also stubs out a subclass of UI document which you usually don't need because you've already created that yourself and it also stubs out an MVC to show the document just this really dumb MVC and you don't need that usually either because you obviously have an MVC that shows your document or you wouldn't be writing this app and finally it gives a subclass of UI document browser view controller which services its own delegate it just has like five methods in it that are really simple and we're gonna go over those in detail so after you create a project with this template what do you need to do to get your app working well one you've got to have your own UI document subclass of course two you've got to have your own document viewing MVC right like emoji art view controller or your image gallery view controller whatever from your homework then you have to add a little bit of code to this UI document browser view controller subclass that comes with the template in its viewdidload you're gonna configure it a little bit it has a couple of bars you can set we'll talk about that you're also going to have to provide the URL of a blank document and this is so that when the user goes into the UI and says create a new document okay you're got it's got to copy some you know template some blank version of your document to be that new document so you just have to give the URL of a blank document to so that you can support document creation and then finally the code you have to put in there is when someone wants to open one of your documents you have to write the code to put an MVC on screen and you don't do it with segwaying so we're gonna learn a little bit new way to put an MVC on screen that does not involve segues and the last thing you want to do to the template of course is update those types the document types to be not be image but to be JSON or emoji art type or image gallery type for your homework or whatever so those are the only four things you do once you do those four simple things you'll get this full UI so steps one and two you've probably already done in your app step three looks like this is viewdidload of UI document browser view controllers subclass and the you really have to do the first thing which is set it has its own delegate because it actually implements a lot of these opening file methods and stuff using its own delegate methods then you can have some things like allows document creation equals true do you allow people to create documents in your app or are you just a document viewer do you allow multiple items to be picked in other words can the user go in and like shift-click or whatever the equivalent is with the touch interface to choose multiple items and open them at once like emoji art can't do that it can only show one document at a time then you can also tweak the look of the UI a little bit okay change the colors a twin colors and things like that to try and match your document controller when it comes up have the same kind of look so that's it that's how you configure it in viewdidload that's most of the settings that you can set and then you have to provide this template URL you do a kind of in a weird way there's this method document browser did request document creation with handler okay that's the method that saying somebody wants to create a document of your type in your app what you got to give me is a URL to a template to a blank and the way it makes you do that is it hands you a little function called the import handler there it's called I guess I called it handler to make it's much shorter but it's actually called import handler and it just takes a URL which is the URL of a blank document and then the import mode which is either copy this or move it to create a new document so it would be move if you created this thing every time this got called its copy if you create it once and then you hand it out every time someone says new document okay and that's it all you have to do is call that handler super simple you'll see that in the demo next you have to present your document NBC so we have to take a little time out and go to an aside and learn something different which is how to put an MVC on screen without segwaying okay so how do we do that it's quite easy there's a in uiviewcontroller called present animated you send it to yourself if you're a view controller and you give it an argument of another MVC and it presents it animated and it presents it on screen modally which means it takes over the entire screen okay and just owns the entire screen until it dismisses itself and then it's back to you okay which exactly what we want here so the trick here though is how do I get a new MVC to present and I told you actually earlier that iOS has a few NB C's like the camera take picture taking MVC and some things so it has some but what if you have one of your own okay well it's really easy actually you just put it in your storyboard okay it won't have any segues drawn to it but what you're gonna do is you're gonna name it you're just gonna select it go to your identity inspector there's a little storyboard ID in there you give it a name and then you use that name in your code like this okay you get an instance of your storyboard which you get by saying UI storyboard name and you know that our storyboard is always been called main storyboard but we haven't talked about the fact you can actually have multiple storyboards perfectly legal we always just say that main and bundle is almost nil there cuz you got your main bundle nil means your main bundle so you get the storyboard and then you ask the storyboard to make you an MVC with that name by saying instantiate view controller with identifier and that food that you have there is the thing that's in my identity inspector for that MVC for the control or top-level controller of that MVC okay and that's it now you just prepare that thing in this case you know by setting its document and then you just present it so it's really really easy instantiate view controller with identifier is the key method that you need out of storyboard alright so back to our present so we need to write be able to write a function that presents it and it's really simple or it's gonna get our storyboard we're gonna stanchion our view controller from the storyboard now really importantly we're gonna set the document of the document showing MVC that we just got of the storyboard we're gonna set it to be a new document with the URL that's passed to us because its present document at URL now this might be a new document it just created by copying that template or it might be some document we're oh that was created in the past okay you don't know and you don't care here okay and then you just call present of that document VC that's it okay you do all that and it just will all work of course you want to set the types that you do JSON or emoji art whatever and we're gonna see all of this happening in emoji art so let's jump right into the demo I'm doing this in emoji art now emoji art is kind of an obvious app to want to turn into a document based app because we're building these beautiful works of art with emoji right and we certainly would what might want to do multiple of them not just have to constantly be working on the same one so there's something about our MVC though our emoji art view controller the view controller that shows our emoji art document it has no model right we have no model in this thing it's just all view okay all the emoji art view especially so I'm going to add another section here at the top to put my model I'm gonna put this in my model section right here everyone remembered that these marks that you put that causes it so that when you go up here to the top you these are like in sections you see the sections there so I've added a new one up here model and you can click on them to jump to the different sections so my model it wants to be some sort of VAR I'll call it emoji art and it's going to be of some type like emoji art okay this type doesn't exist but that's kind of what my model wants to be so let's invent a struct here or a class or a struct that represents an emoji art document well what's in an emoji art document there's the URL of the background and then there's all those emojis what they are and where they are and how big they are right that's what an emoji art document looks like so let's go create a model to do exactly that so I'm gonna create a new file just a model file so we're over here and swift not over here a cocoa touch or over here was to a file okay I'm gonna call it emoji art it's perfect sense to call it that here it is I'm going to type it in really fast OOP there it is and so here it is makes perfect sense what it is right a URL that's for the background then an array of these emoji infos which is this thing and each emoji info is position X&Y the text that's like a bike or the B or whatever the string is and then the size which I'm gonna have to be the font size notice I've made these intz instead of CG floats or whatever because this is a model okay this is not a UI thing it's there's our model so these could be in sorta they could be doubles but I decided I want an inch because I want my Jason to look nice not have a lot of fractional numbers and all that stuff so I decided to make them an inch and that's it that this fully represented emoji our document this has just initializer to the initialize of those two things nothing else to it but this all right now let's think about our emoji art view controller back here what does it need to be able to interact with the model well it needs all those little UI labels that are in this emoji art view no problem we can get those where the controller we can talk to our view and get anything we want from it but it also needs to URL and currently we actually don't keep the URL for the background image okay let's go scroll down to where we get that image just right at the bottom here when we drop an image and you can see our image fetcher goes off and fetches that URL an image but then we only use the image we don't use the URL okay so we're gonna start doing that and I'm going to do it in a way just to show you a little bit more kind of Swift program which is I'm gonna make this VAR which is currently a UI image be a tuple okay and why would I make this a tuple well I make a tuple because I want the URL and the image to always be set together I would never want to actively I said the image and have the URL be different okay so I'm gonna always set them together so I'm going to change this from being a UI image to being a tuple so let's go find out where it's declared here it is it's currently aur UI image I'm gonna change it to be a tuple that has a URL and an image as part of the tuple and of course changing this thing's type is going to require me to change this implementation a little bit like all these new values down here aren't you eye images anymore they're this tuple so we got to say new I'll value that image when I want the image that image and of course when I'm returning it I can't just return the image here I have to return a tuple with some URL of some sort and that UI image and what URL am I gonna return well I'm gonna have to actually store that so I'm gonna make a little private bar I'm gonna call it emoji art background-image:url which is gonna be a URL and I'm gonna store it in there okay now I'm not gonna want to set it from here I'm gonna always want to set it from here but I'm just gonna use this as storage some people might put an underbar in front of this here to kind of emphasize that this is background storage okay we're not going to ever set this directly we set the URL here so it's always said the same so I'm gonna leave it under bar there too so this URL here then is this one so I'm just gonna return this URL and of course when I set I need to set the URL tier to be this new values URL okay so now I'm capturing the URL all the time I always have the URL anytime I have an image I'm that's good I'll need it for my model okay now let's talk about the model here we could have this model just stored like this and then have some other functions that like go and look at all of our UI labels and grab the URL and build in emoji R and in return but you know I'm gonna do something kind of fun watch this I'm gonna make this a computed property okay this is my model but I'm making computed and why am I doing this well anytime someone wants my model I'm gonna look through my UI and make it for them and anytime someone sets my model I'm gonna go update my UI to be like that that way these things can never be out of sync my model will always be a perfect match with my UI and that is a really good thing to have in a controller is the model and the UI always in sync so that's why I'm gonna do this again I think it'll work out nicely here all right so what do I need to do to get my model I gotta return the URL and I got to return all those little emoji infos right I'm a bench eventually gonna have to return some emoji art by calling its initializer URL with some URL and the emojis with some emojis okay so we need these two bars to be created well the URL is really easy I'm just gonna say if I can let you RL equal my emoji art background image dot URL that's it URL if I can do that then like I'm ready to return something here by the way if I can't do that then I'm gonna return nil because I don't really for me my emoji art is not really well-defined if it doesn't have a background okay it doesn't really make sense to have emoji art where there's like a bee and a bike on a plain background we don't really support that so I'm just gonna say if you asked for my model and I haven't don't have a URL yet and I'm just gonna say I don't have a model yet I've not been created enough to say that I have one okay so that fixes the URL how about this emojis thing right here we have to set this emojis bar right here so I'm just going to say let emojis equal and essentially what I want to do here is go ask my emoji art view for all its sub views but I really don't want all of them I just want the ones that I can get as a UI label okay I'm using map here you all know map so this returns an array of UI labels the only thing about this is this might return nil so I actually won't use a different map called flat map so flat map it's just like map it's just that if the little function returns nil it ignores it okay so it flattens it down to not have the nil ones all right so now I have all my UI labels now I need to turn this into an array of these emoji infos right because that's what I'm doing I'm returning my model so how the heck am I going to do that I'm definitely going to need a function that takes a UI label and return to one of these emoji infos and you know what I'm going to do I'm actually going to do that by writing an extension to this struct and I'm going to put that extension over here in my controller because that extension is gonna take a UI label as an argument and return an emoji info as the value and that UI label is a UI thing so that could not be in my model okay but it can be in my controller and this is my controller and some people say well wait a second if you put an extension here two emoji info you've just added UI to your model no okay this is my controller okay not my model the fact that my controllers implemented this with an extension this extension lives in my controller so that is perfectly legal to do and you'll see iOS do that where it'll have something like NS attributed string which is actually in foundation not a UI thing but when you start adding attributes like font and so like that now it becomes you I think all that stuff is implemented in the UI kit it by extension to NS attributed string we're doing the same thing here so I decided to do this instead of with a function I actually add an extension that adds a new initializer to emoji info okay initializes it with a label and if I can get the attributed text out of there and get its font then I can make myself an emoji info if I can't I'm gonna return nil so this is a failable initializer this is how you fail out of a failable initializer okay so now that I can do that so easily I'm just gonna take this array of UI labels right here and I'm going to flat map that and the thing here I'm gonna say is return an emoji art emoji info using my nice new label initializer and remember that dollar 0 right here is these UI labels yeah you got that kind of cool all right so that's our emojis that is creating our emoji art that's it that's all we need to do to get our model how about the set side of it well the first thing I want to do when someone sets a new emoji art is clear out what I've already got in there so I'm gonna set my emoji art background image to nil nil common nil it's a tuple remember and I'm gonna set all of my emoji art views sub views okay but actually only the ones that are labels I'm going to send a message to all of them for each to remove themselves remove themselves from their super view super yeah okay so I'm just taking all the labels are there and removing them because somebody set a new model so I'm clearing everything out here Oh ask question mark okay so now I've cleared everything out now I need to put this new thing in well to put the URL in I'm gonna need to fetch it okay so let's fetch it okay here's how I that's right here's my image fetcher thing the same thing I did when someone was something was dropped and back I'm gonna do this back on the main queue because now I'm gonna update my UI with this your URL when it came back okay so what am I gonna do when this thing comes back first of all I gotta set my background image so I'm gonna set my image whoops my emoji emoji art image background equal to the URL an image that came back again this is a tuple I'm setting it from here coming back from the image fetcher and now I need to add all those labels for all the emoji right the be using the bikes and everything that I've dragged down I gotta put all those in there so let's do that probably the easiest way to do that kind of conceptually I want to take this new value of the emoji art and look through all of its emojis and for each of them I kind of want to just ask my emoji art view art view to add a label with the right arguments whatever for each one right this is conceptually what I want to do well actually I have ad label into my emoji art view but I made it private so I'm going to go over to my emoji art view and make that public and remember that I'm the controller over there I can call anything I want in my view 'maybe you can't call anything in me without blind structure communication but I can call anything I want in it so here we have label it looks like it wants an attributed string and the point that makes sense let's go back over here and do that so the attributed tributed text is that what they called it we want some attributed oh no it's just with I think with yes with attributed tributed text and centered at actually already know centered at centered at is just the CG point with the X being this dollar zeros X and the why is this dollar zeros y okay because dollar zero is each of these emoji so it's an emoji info okay and emoji info just to remind you is this thing so the X and y is the X&Y position now I need to deal with the text and the size so let's do that I'm gonna do that by letting that attributed text argument equal the text converted to attributed string I actually have this nice little function I wrote in utilities called attributed string with textile and so I'm going to make it body font of a certain size which is a CG float of the dollar zeros size so there there we've set now if someone sets our model boom we've set everything okay our UI should match okay now we're in great shape because we've got an MVC here which has a model that we can set and get that makes our UI work and all we need to do is make it persistent okay make it store on disk and we're gonna make it persistent by having this emoji our thing here become codable and be able to turn itself into a json and then we're gonna use JSON as our file format okay so let's go back to emoji art over here and make this thing generate JSON and we're gonna do that by just saying that it is codable okay and when we put codable on there and we recompile we're gonna see if there's any problems with this and see whether it is codable or not so let's find out and it says it's not okay it says it doesn't implement decodable and end codable which are the two protocols in this codable protocol why not this is codable an array is codable oh no this type is not codable oh we have no problem calling codable we made that come up codable and now we'll let this thing recompile it era era went away look at that we just made emoji art codable and this is why I was telling you about this codable stuff the new kind of archive is so easy because you don't need to do all that Indian sand decode and encode and all that stuff for 90% of all Struck's it'll just do it for you now again our json keys are gonna be the same as our variable names okay when we do the json which is good in this case because they're all nice in it but we could change it by adding that private enum coding keys colon string remember that slide we're not going to but but we could do that all right now how about the JSON how do we get the JSON version of this well I'm actually gonna add a var to this emoji art called JSON and it returns a data optional it's possible I guess we might not be able to turn ourselves into JSON but I think 100% we would but I'll make it a data just to be clear and I'm just going to create a JSON out of myself by returning trying to use a JSON encoder to encode myself and that's it okay that's either gonna return a data of myself at JSON or nil if it couldn't do it now this is never gonna fail I'm so confidence is never gonna fail I could even do try exclamation point right there and not make that an optional because these types are all 100% encode Abul okay but I'll do this just to kind of be correct programming so now we have a way to turn this thing into emoji art so let's add a little bit of UI to our mochi art to have a button I'm gonna call save which you press save and it's going to eventually save this JSON this emoji our document to disk as JSON but first we'll just have it print the JSON out on the console so we can just see what's going on here so let's do that let's go to our storyboard and add a Save button here now if we look in our storyboard look we've got a lot of junk in here okay this is that table view that we put to try and have our documents in a table view hmm well if we're gonna have a significant upgrade here because we're gonna use that nice files app thing so I'm just gonna delete this junk okay get rid of all that and I'm I want to now put a Save button somewhere here in this UI you know I'm gonna do I'm gonna embed this in a navigation controller so that I get the little title bar at the top you see this little title bar that comes at the top because that's a good place I could put a little Save button to okay so throwing things in navigation controller to get that title bar it's actually quite common and quite a nice feature so let's go down here and search for a bar button bar button here it is we always use bar button in these bars not regular buttons and I'm gonna inspect that bar button and make it be a safe okay standard button called safe there it is let's wire it up target action into our controller here so control drag down here it's going to be an action I'm gonna call it save it's gonna be a bar button item as its argument there we go here it is let's go back to full screen so we can get the whoops get the full width here to do our save so this save I just want it to print my model out as JSON on the console so to do that I'm just gonna say if I can let JSON equal my model if I have one its JSON JSON okay now I have the JSON it's a data though okay and I want to print it out obviously as a string and when your have a data and you want to print it as a string you have to tell the system what the encoding is like is it ASCII okay or Unicode some sort of Unicode thing well JSON is always utf-8 which is Unicode encoding coding 8-bit encoding so we're just going to let it's an if ya if let JSON string equal string constructor with taking that jada that I have and telling it what the encoding is which is dot you can see there's a lot of different kinds of you know ISO Latin one and shift gists and all these things I asked you right there but we're gonna do utf-8 okay so if we're able to do that then I'm just gonna print it print JSON string okay so now our Save button is gonna print it out so let's go ahead and give this a try you can see a little bit of warnings over there that's just because of that oh yes okay that warning is a good warning let's go look at this warning right here it says unreachable part of our storyboard and indeed if we go look at our storyboard over here where is it we have no entry point to our storyboard cuz member I deleted all that junk well I deleted the entry point with it so let's select this navigation older and go over here and inspect it and say this is our initial view controller okay so you got to pay attention to your warnings over here right okay so let's bring our console back up make this as wide as possible run go back take a look here alright this time it's running so here's our emoji art right here let's go ahead and make a nice emoji our document about what this thing right here and let's put a little bicycle on the road right there okay now I'm gonna hit save and let's watch our console over there oops save nope there it is okay here is our emoji it's got the URL which is this really really long Google image emoji and then it's got the emojis which is an array that only has one thing the bike in it so let's add another thing my second favorite thing to add which is a B and save okay and now a JSON has the B in it as well okay so with very little work here just by making that thing codable we have made it so we can save our document in JSON format so now let's add the file system code to actually write it out to disk okay that's gonna be our next step here so let's go do that go back to our controller here so instead of printing this thing out as a JSON we're just going to write this to disk now this is of type data right it's a data so I can just write it to disk with JSON dot right to URL now a couple of things one we have to say what URL are we gonna write it to and of course this the rows so we're gonna have to deal with both of those things first let's talk about what URL we're gonna write it to well anytime you're talking about the file system what's the number one thing you have to do when you create a URL find a directory in the sandbox to start okay always do this 100 point over cent of the time you're going to write some of the filesystem or read something from the filesystem you've got to figure out which sandbox directory you're gonna start in so this is a document so I'm gonna put it in my document directory okay so I let's type this in here okay this is how we look up a sandbar Ector e here this default file manager default method you are so we're looking for the document directory we always do user domain mask we're not replacing a file so we don't care about that and we wanted to create the documents directory if it hasn't and then I'm going to append the name of my file on to that URL for the document directory untitled' Jess on I'm gonna call it okay so now I have the URL I can put this in here and write it now we just have to deal with the fact that this Thoreau's so that means I have to put try in front of it and I'm going to actually catch errors from this catch blipped catch let error and here if I get an error I'm gonna say print couldn't couldn't save and we'll put the error right in there so we can see what it is but if it doesn't fail then I'm gonna say saved successfully okay so now when we run on our console we should see either shape successfully or couldn't save so let's go try this yeah did all the code on here at the same time so you can see it run again it's got here see that okay so one thing about our app of course every time it starts we it doesn't load up the document so it's always blank so we always have to start again so here let's start again with this one okay let's put an apple in this guy up here and I'm gonna hit save now and hopefully it'll say save so successfully in our console already well who saved successfully good to add another some coffee save successfully actually it's working but this is not very satisfying because it's just saying save successful and you're like oh yeah sure well you say it's saved but did it really save but actually we couldn't go look and see if it's saved and go find this document because we have the iOS 11 files app ok which lets us look at documents in apps that opt-in now the key there is apps that opt-in so we have to actually put that little info.plist thing I was talking about that says we are an app where you can look in our document directory and see our documents so let's go do that we're just going to jump over to our info.plist here I'm gonna do the same kind of thing that we did in your homework where you added a row remember that to do the HTTP URL so I'm going to add a row support document browser there it is okay so where's document browser and I'm gonna set that to yes okay and that tells the system okay you can look in my documents directory and see my documents okay so I have to run again because we have to transfer the app back over to the iPad so would look at this info.plist over there but actually I don't even need to create that untitled JSON again it's already there okay so I swiped up from the bottom to get this little thing to appear on the bottom here and I'm gonna click touch on this app right here that is the file's app and you're gonna see the UI here for files this is a lot what your UI is gonna look like in your app okay so it's got all these nice folders right here you can arrange them by dates and tags a name you can go put things on your outcome drive you can put things on your iPad and here I'm clicking iPad emoji already is the only app on my iPad currently that has a documents directory with documents that I file files is allowed to look at that's because this iPad is pretty much fresh install but here it is my app and if I click on this notice it puts my app icon in that's kind of nice if I click on it whoo-hoo it's untitled JSON and I can long press on it and say info and it'll even tell me look this is a kind of a pilot's JSON file has 656 bytes that sounds about right right that's about how many things we had in there and I can even click on it to view it however look where it views it whoop okay in some sort of JSON viewing app of some sorts not in our an our app so that's kind of weird why is that well because we're not a JSON viewing app we're an emoji art app so the files app doesn't note that we are the one to open there and we can fix that a little bit later we're probably not gonna have time to do it today demo but I will certainly do it in the code I post and show you and the fix to that is to define a new file type called emoji art and then the files app will know oh that's an emoji art thing but right now it looks at the extension JSON and says well I'm gonna do the JSON thing and you can tell you let's see it's right though it's got the Apple it's got the coffee in there it's really small but you can see it okay so that's great so we know it's actually saving so let's go to the next step which is reading this document so let's have our app every time it puts interview controller up viewwillappear will do it in it looks for untitled JSON and loads it up that way every time we run our app it won't be blank every time it'll just load the last document we were working on the untitled JSON that we were working on okay so let's do that go back to whoops go back to our controller here's our view controller right here so we're gonna do that in viewwillappear let's do view will appear super dot view will appear animated okay so what do we need to do in here in view will appear to get this to appear it's pretty straightforward we just need to get that URL for the untitled JSON and then look at the data and turn it back into an emoji art and set that as our model okay at that so let's do that of course I need that URL so I'm gonna do the same thing that I did before I've got what I call that Alette URL yeah so here's where I go get my document directory and append the path component of untitled JSON this is exactly what I need up here okay no different because I want the exact same URL but here I'm going to say if I can let JSON data equal trying to have data contents of exactly the same thing this data contents of is exactly what we did to get image URLs over HTTP right so contents of the file URL which is this untitled JSON file in our documents directory that's what this URL is so if I'm able to create a data out of that file now I need to create an emoji are out of it and set that as my model so emoji art is my model let me said equal to I need to create an emoji art from some JSON data okay well we don't have an initializer for emoji art that creates an emoji art from JSON data but we can really easily write one let's go back to emoji art over here and just like we wrote this to get the JSON we can certainly write and initializer which I'm also gonna have buffet that takes some JSON which is a data and initializes and if I can't initialize it then I'm going to fail and return nil okay so what does it look like to do this again really easy I'm just gonna say if I can let new value that's gonna be my new value that I pull out of there equal try to JSON decode oops decoder decode and what am i trying to decode out of that data I'm trying to decode an emoji art object okay and from what data the JSON that you passed in okay so if I'm able to do that if I'm able to decode it out of there now I have it the new thing a new value and so I'm just gonna say self equals new value right I'm in an initializer here so I'm just going to initialize myself and I'm gonna fail otherwise by returning nil now this one's much more likely to fail because you can imagine corrupted JSON just playing the wrong JSON file okay an empty JSON file all these things would call this a fail and that's fine it's just this will not initialize this is only going to initialize if this is valid a valid JSON encoded something from this basically that's the only way to ill succeed so now our code will work over here right we've got this implemented so now when we quit and go back our document should be there so let's do that I mean I pad up here let's run and then show it to you okay here it is and sure enough look at that it already picked up that untitled JSON and if I add a dog to this and hit save okay then quit and run again comes back with the dog so we're both saving it okay with the Save button and review will appear we're loading it up so this is excellent okay we're really making a lot of progress here but now it's time to take this to the next level which is be able to do that files app kind of UI and to do that to make that easy and to simplify our existing code actually we need to use UI document ok UI document encapsulate a document into just this really beautiful wave really nice API and that's what we need to do now we could just do that here all I'd have to do is create a UI document subclass and implement the two methods I talked about in lecture on Monday but this is where we're going to step in and use that template okay we're going to throw that template in here for document base so I'm going to stop my app right here and I'm going to rename my existing mode gr I'm just gonna call it emoji art old okay and then I'm gonna go back to Xcode and create a new project okay and this new project I'm going to use this document based app right here I'm gonna call it still emoji art basically this is gonna be the same app it's just gonna have this built on this template okay I'm gonna put it the same place I put everything else okay here it is let's quickly look at the things this created okay it's just a normal kind of a Xcode app so of course it has assets and launch screen and app delegate so I'm gonna put these three things in a little supporting files like you always do however I'm gonna take a moment to take a first take a look at the app delegate because the app delegate is not just a bunch of empty methods with just comments only it also now has this actual method this method is called open input URL this is sent to your application by other applications like files that say I want to open up one of your documents now this is only going to get called if we have an emoji art document not a JSON document cuz we're not an open case on opening app but this is how that happened this pretty simple code I'm not going to go through it but this is where that's going on and we're gonna talk all about app delegate all this stuff next week all right so we got this 14 files what else came over there well we have this UI document subclass called document well this is going to eventually be our emoji art document okay emoji art let's even rename the name of the file to be emoji art okay so this has got those two functions right the one that converts from our model to a data and from our data to a model back and forth that's all we have to implement to make this work so we'll do that in a little bit then there's this document view controller is basically like emoji art view controller right it's just this stub for a document view controller and of course we have emoji art view controller so we don't need this so I'm just going to right click on it and delete it okay so I'm going to delete this document view controller I don't need it I have my emoji art view controller and then there's this document browser view controller thing right here this is the subclass of UI document browser view controller here's that viewdidload I was telling you where we're going to configure it here's the place where we're gonna call this import Handler to copy a template here's some other methods that we're not even gonna have to touch that just get called when it's time to open a document and then there's this one down here present document which I'm going to delete most of this is just an internal method that's called from all those other things that says okay present your MVC for this document at this URL okay so we'll be implementing that soon and then of course we got our storyboard let's see what's in our storyboard I'm gonna make our storyboard look more like an iPad little more familiar to us although our app will work on iphone by the way after all this I will show you that hopefully we have time so there's only two view controllers here in this storyboard one is this one that's the document browser view controller that's the thing that looks like the files app okay and notice that's where we come in okay we arrived into this app there then there's this this is going to be our emoji art view controller in fact I'm going to delete the one that comes in here because it's just a little placeholder and I'm gonna put my emoji art view controller here and let's go do it right now in fact I'm gonna go back to emoji art that old here I'm gonna go to its storyboard and one thing that's really cool about storyboards is that you can copy and paste from one storyboard to another because all the connections to the code are made by name okay it's only just the name so as long as the names are the same in both way it places it work so I'm just gonna select all of this and hit copy okay then go back to my new one here and hit paste okay zoom out a little bit so we can see it all our document outline and make this look nice here now one thing to notice I know this is a little hard to see on this screen so I'll try and zoom in more but you notice there's no segue between here right these live on their own this one lives on its own and that's why we have to do this manual presenting the other thing I'm going to do for now is I'm gonna have the entry point be our existing view controller we'll add this one in once we get the UI document stuff working because we have to have UI document working before we can really leverage this so we're just going to have our old UI for now and I'm gonna try and get our existing app as we had it before working with UI document so it can be exact same thing but just working with UI document instead of directly accessing the file system there so of course we also need to have all of our files from the old one so let's go back to old emoji art here and get all of our stuff out of there oops this getting these two things on the screen same time on this very small screen can be a challenge alright so I'm going to bring over my controller my model my view some of the supporting files like the cells the gesture recognizer stuff the utilities the stuff I did I'm not bringing over the app delegate because that came with the with the template so I don't want to do that and I'm not bringing over my table view controller either that's what's under junk here that's the table view controller that was supposed to be the documents thing that we said forget that we're using this new files thing so I'm just gonna drag these over here then copy them all in and one other thing I want to bring over actually from here is my app icon okay I got this nice app icon don't to lose that so I'm gonna go over here to my assets in my new one and get rid of the blank app icon and just drag this app icon over here okay so that's it so I've essentially brought over everything from my old emoji art to the new emoji art but what we're going to do first is go and make this emoji art document business work so let's go do that where is our emoji art document it's right here okay this is the thing I just renamed and there's only these two methods they're doing stuff we know exactly how to do we were just doing this one thing about this is you notice that contents returns in any knotted data that's because this any could be a file wrapper okay a directory full of files is a way to represent a document just like is a data is but usually this is going to return a data in fact look the default returns a blank data so here to do this to do either of these we actually need that model pass to us in the document so I'm gonna have a var emoji art over here as well which is gonna be an emoji art and any time I want to save my model from my controller I just take my controllers model and put it in the document and then the document knows what to do from there so let's go ahead and return this emoji arts JSON and if it doesn't have JSON representation then we'll return data which is a blank document okay empty document and we know how to deal with that because our documents always come up empty and then this is the other way around okay here we're having one passed to us okay a data passed to us and we want to turn it into an emoji art so I'm gonna say if I can let the JSON equal the contents that were passed to me as a data because I don't deal with file wrappers okay this or a file wrapper I don't deal with that then I'm going to set my emoji art equal to again using that constructor that I did to take a J data and turn it into an emoji art and this might fail and that's fine and then this will be nil and then it won't save the document okay I guess they have an L document and I talked about this of type in both these cases this is a UTI okay like public JSON is a UTI or edu not stanford cs193p I'm og art could be a UTI okay a unique identifier of the type now we don't really care cuz we only open one thing or anything we open JSON or an emoji art whatever is all just a JSON data anyway to us so we don't care about the type but some apps might open multiple different types they might need to know what type it is in order to successfully open it or save it and that's it this is all we need to do to do an emoji art document we're done now we can use all the API of UI document like this asynchronous opening and saving working over iCloud automatic auto saving all that stuff just all works for free as long as you these things so let's use all those things back in art emoji art viewcontroller here to replace the places where we're accessing the file system directly here okay so we want to get rid of all this so let's delete all that and let's delete all this okay and we're gonna replace this with stuff from using the same primitives but using the document now to do this we obviously need to have a var which is the document because we have to be able to talk to our own document so we're just gonna have a bar called emoji I call document which is of type emoji art document okay this is going to be set in that code from the file chooser right when the file chooser chooses a file we're gonna set our document in our new MVC and then it's just gonna magically show its stuff using all the document API so let's talk about viewwillappear first okay when our first document first appears we need to open our document so we do that by just saying document open okay that's all we have to say it does come with a completion handler that will tell you whether it was successful doing that and we usually want to check this and say if we're there were success then we're gonna do some stuff what might we want to do here maybe we want to set our title equal to the documents localized name okay this localized name just comes from the URL it's like the last part of the URL without the file extension put in there so that's nice we need self in there of course inside a closure but the most important thing we want to do if we successfully open the document is to set our model into to the model that the document was able to get by opening that file okay so the document has an emoji art that it got from the file we have our model we want to get it okay so that's the main thing we are doing in all these document things is for setting and getting our model now what about save okay well we actually don't really do save we do autosave okay so how do we do autosave the only thing that's important with autosave is that you tell the UI document that something has changed otherwise it's not going to waste its time auto-saving something that hasn't changed and you do that by first telling the document to look at your model don't want it said it to our model and then you tell the document that a change has happened so you update the change count and you say that that change is done by the way this done can be undo redo or done so we're not talking about the undo manager so I can't really show you that but the other option is done because meaning the change is done and by the way I'm only going to do this if the documents emoji art is not nil okay if we if we haven't actually started up a document it's useless to be updating it's change go out there okay now this is strange because we are saying and noting that our document changed because the user pressed the Save button okay that is weird really we should know if that's changed when anything changes someone dragged out another emoji they resized it they put a different background URL that's when we should quote save and really this method shouldn't even be called save it should be called document change well unfortunately a time when the we want number one thing it's going to cut off that I can't get done because this midterm coming in here is putting that saving or the document change tracking in and why is that an interesting thing well because that's being tracked in our view right our view is what knows when we've resized something or drags on the end so our view needs to talk back to our controller and say hey something changed well it can't talk back to our controller except for a blind and structured right so what how would we any of you here how would you suggest that we talk from our view back to our controller to tell it hey this document has changed this document has changed what would suggest mechanism okay so one suggestion is let's have a variable in our view that's a reference to our controller and that's not allowed by MBC right view can't talk to its controller that way so let's try delegation okay the same way a table view talks back to its controller it is a delegation a scroll view it uses delegation that's how we would have to do it so we have to set up our own delegation where we have an emoji our view delegate okay that's what we would do I'm first I don't have time to do that but that's what we would do so I don't want you get the idea here that you'd have should have save buttons in document apps you should never have a Save button okay it should know when things change and just call this update change count okay but since we don't have that we will have our Save button we will just tell it when it saves all right okay what else do we have to do here how about closing our document right now we only have one document untitled JSON but we're just about to ask at a file chooser that's going to let us choose lots of different documents so we need a way to close this document so we can open another document so I'm gonna go back and add a close button to our UI okay I'm gonna put it right here on the other side from save over there here bar button again and bar button appear there's actually standard one for that it's actually called done because you're done with this document right there and we are then going to control drag I'll put it right in here and I'm gonna have an action here I'm gonna call it close you could call it done but I'll call it closed okay and now let's go back to full width here go back over to here alright so what are we gonna do in our clothes well for a document apt it's easy you're just gonna say document close okay now it also has a you know success completion Handler but I don't really care because I'm not gonna do anything whether it's successful or not I'm just going to try to close it and hope it will be and it 99% of the time it's going to be I could you know catch your errors and some of having problems for some reasons closing and having problems but the best week really do is just try to close and see what happens the other thing I'm gonna do is I want to save right now because I don't have automatic change tracking I want to save before I close if I had automatic change tracking I wouldn't do safe here okay I would delete this line of code and in fact I am gonna delete this line code when I post this code after lecture because I'm gonna have that change tracking in there now I notice I did save with no argument because save takes a bar button item and I don't have one here's a cool trick I'm gonna make this an optional and have a default to nil okay by doing that now I can call save with nothing and it defaults to nil and I don't use this bar button item in here so all is well okay everybody got all that okay now to test all this this is it see how we've replaced all that stuff in our that was file system now with all this nice code that's very understandable and readable open our document close our document update the document I'm going to in my viewdidload set my document to be untitled JSON okay eventually it's gonna be that chooser thing but for now it's gonna be that so in viewdidload just says this is just as a test I'm going to take this right out of here right after we do this test and all I'm gonna do here is get that that JSON URL again okay you can see why I put that in Elko to knit because I have to type to so many times and all I'm gonna do here is just set my document right that's this bar right here okay it has to be an emoji art document I said that equal to an emoji art running out of battery there document and remember that UI documents only have one initializer it's the URL okay so this is file URL the URL okay since there have my cold close curly braces there we go so that's it so I'm the only doing that just as a test so now when we launch our app it should load that untitled JSON up because we're immediately setting that as our document and the document just does its thing so let's go ahead and take a look at that here run and let you see what's going on okay look it loaded up on title judge JSON and let's put a little airplane flying across there and I'm gonna hit save to let it know that there was a change to the document and then hit done okay now if I quit and run again hopefully we'll see the airplane there and we did okay so you why documents doing all the things the file system stuff was doing for us but now the way of UI document we can have our app launched instead of launch and show this launch and show that file choosing thing the document browser thing like the files app so let's go put that piece of the puzzle in here before I do anything I'm gonna make sure I remove this viewdidload okay I'm gonna take that away because I'm not going to be setting my document to this and untitled out JSON I'm gonna be setting it to whatever the document view browser wants me is have it be alright so here we are this is the document browser view controller this is the thing where all the magic happens here one thing we have to do to get this guy in the loop is to go back to our storyboard and have the entry point no longer be our MVC instead it's going to be this okay and we're gonna be responsible from getting from here to presenting this on top of this to show our document so let's see how we do that all right so let's do all the parts I talked about in the slides here let's do viewdidload let's configure so of course we want our delegate equal self we need that also we are not going to allow picking of multiple items because we only know how to show one emoji art document at a time allows documentation be true mmm yeah for now and then here is things tint color I'm not gonna change the color or the look of it you can play around with that see what you like there so we're gonna come back to viewdidload and address this in just a moment but now let's go down here to did request document creation with handler this is where it's saying give me the URL of a blank document because someone wants to create one and I'm gonna make this really easy on us here I'm gonna delete all of that in there and just call this import handler gave me see it's giving me this import handler it takes a URL and either copy or move and I'm gonna call it with a template which is gonna be URL and dot copy and all I have to do is make a URL bar template URL okay make this template point to some blank document and I'm going to do that in viewdidload right here okay and let's add a little here and to do that I'm just gonna get a URL this time not into my documents directory because this is the blank document I'm copying all the time I don't want to appear in the documents when the guy goes when the user goes and looks there so I'm gonna put it in application support so application supports a great place to put things that are kind of behind the scenes okay but they're permanent I want this template to stick around I don't want to be the cache doesn't get deleted although I probably could put it in caches because I can always recreate it here in viewdidload but anyway so this is the URL I'm gonna call it untitled JSON just for old times sake okay I'm putting in my application support directory and all I want to do here though is make sure I create this file so I've got the URL to it so to create it I'm gonna say if the template is not nil in other words I've got I was able to create the URL which I should be able to I'm gonna now set allow document creation this VAR up here instead of it being true I'm going to set it to be the result of asking the file manager the default file manager to create that file so it has a method called create file and give it the path to the file the templates path and you create it with some contents I'm gonna make it empty because it's just a blank document an empty document and I don't even need any file attributes so let's get rid of that now create file is a nice way to create a file because it doesn't throw or anything like that and it returns a boolean whether that file either got created or already exists which is exactly what I want here and if it's true then I will allow document creation otherwise I'm not gonna allow it because I couldn't create the template see why I'm doing that right there so that's a nice little trick to kind of do when you're creating your template if you fail to create it for some reason you can you can do that so now this import handler will just work okay I'm passing it this template then up here and having it copied out of application support into the documents directory these other things over here we don't need an even touch these are the things they get called when people click on documents ok did pick document URLs did import document is when some other app like the files app asking you to open up one of your documents and notice that they're both doing the same one liner which is please present the document at that URL that means put up your view controller to show it okay so we and there's a by the way an error one here seed failed to import document add you really should put up an alert here but I haven't shown you how to put up alerts I'm going to show you next week so you can't do it but that you really should put an alert that says couldn't load ocular couldn't open document or whatever all right so here's present document that's going to present it and I'm gonna basically do what I showed you in the slides right here which is I'm going to get my storyboard there was already code to get the storyboard in here from that template and I'm going to use the storyboard to get the view controller that I want to present now it's a little tricky here the view control I want to present is actually not my emoji art view controller it's the navigation controller it's in everyone understand that so I have to somehow instantiate this navigation controller which will also bring this in so I need to give this guy a name so I'm just gonna select it go to the identity inspector and give it a name I'm going to call it my document MVC okay it can be any name we want but document MVC is kind of what that is at the top of my document NBC mechanism so now that I have this name I can go back here and say let my document document VC equal the storyboard not instantiate view controller with identifier document MVC okay so now we have our document MVC and I'm now just going to configure it and then I'm going to present it by saying present the document MVC VC rather and animated true and one animator true because I'm going to clicked on it in the file so we want to line up right we don't just appear we want to slide up in the bottom there's even a way to make this like grow out of the icon in the files thing which is really cool it's not even that hard unfortunately I don't have time to show it to you but just know that there's a way to do it this is going to be this normal slide up from the bottom presentation but this document NBC has an emoji view control learning it that we need to set the document of so I'm going to do the same kind of thing we do in and prepare I'm gonna say if I can let my emoji view controller equal the document view controller its contents remember that contents I showed you that before let's go look at it just remind you I have this in utilities the contents is a uiviewcontroller method right here that just says if I'm a navigation controller return my contents otherwise I'm not a navigation controller just return myself so this will make it so that this code that I just wrote will work whether it's wrapped in a navigation controller or not okay so get the contents as an emoji art view controller view controller view controller okay so if I can get the emoji art view controller I guess I should call this emoji art view controller to be nice there then I can set its document emoji art view controller dot document equals and what is the document equals it means equals a new emoji art document which we know the constructor is file URL and what's the URL it's the URL they want us to present document URL okay what is this a instance member Oh capital e there we go okay thought it would wanted a static method there okay okay one sorry one other thing we need to do is the types right now if we go look at our project settings right here I'm gonna go over and look at our project settings and we look at the info here the document types that we can open our images okay and we don't open images we open JSON files okay public dot JSON and like I said when I when I post the code after lecture I'll also do this exported UTIs down here and make a new type emoji art and then put that as our type but for now we'll say that we do JSON files okay so if I haven't forgotten anything here should work okay look at that already you can see our app is quite different it is showing us a UI that looks just like the files app right got the folders and all the stuff we can even go here over here to iCloud drive we can go on on my iPad there it is emoji art let's look inside okay there is our untitled I JSON let's open it whew it works okay let's close this one let's go it doesn't close look I'm pressing done it doesn't close okay why our MVC comes up it takes over the whole screen because we presented it right here how do we make it go away okay how do we dismiss it essentially well we do that in the view controller itself the view controller that wants to dismiss it dismisses itself and the way we're going to do that is in close when you hit that done button right there and we're going to save but then we're going to say dismiss animated okay and so dismiss animated true is how you dismiss yourself if you've been presented you can dismiss yourself this also has a completion Handler and in that completion handler I'm going to close okay so I'm gonna wait till I've been dismissed the animation has happened then I'll close my document and of course now I'm in a closure so I have to say self okay so let's try that okay so here I'm gonna open untitled again okay now I'm gonna close it and I'm back here now I'm gonna create a document ready create it copies that template it's blank now I'm gonna drag a document in here let's see we find something good here something like that okay put an apple on the tree let's say that okay now I'm going to I'll save just to note that it has changed again we should do that automatically and then I'm gonna say done okay and now we have two documents and now I can go back to the other one right good that go to this one but that one now what if I want to put these things on iCloud Drive watch what happens when we go to iCloud Drive for emoji art create document you see look I can create a document on iCloud Drive so this is actually created on the network I'll be able to see you on all my devices so make another one here like this put a bee out there Big B and Mark saved and then done and now we have this document untitled right here that you see is on iCloud drive so we still have the untitled ones on our device and we have the one here on icon drive and we click on it we get to see it okay now the next thing I'm gonna do is make it so that this UI looks a lot better okay because look at the icons there I mean is that the world's ugliest looking icon so we're gonna go from the world's ugliest looking I got into the world's best looking icons because with UI document you can have each document have its own icon okay and I'm gonna set the icon to be a miniature version of the document a thumbnail image exactly that way I can easily see which one was the one with the Apple and which one has to be it'll be I'll be able to see it right in here so let's do that that turned out to be super simple to do in UI document so I'm gonna go back to my emoji art document here okay this simple guy and I'm just gonna add one method which I'm going to override okay called file attributes to write and this is essentially just returning a dictionary of the file attributes like is this file hidden those kind of things so I'm going to get those attributes from my super class because I'm overriding this so I'm gonna get the super woods and then I'm add one attribute which is this kind of complicated thing called a thumbnail dictionary key actually the value is another dictionary and you put this other key here thumbnail 1024 by 1024 size key don't let that fool you it can be any size you want although if it's too small it'll use the document icon again so make sure it's big enough to actually be an improvement on that and I need to put a thumbnail in there so I'm gonna add a var to be that thumbnail UI image okay somebody else just a UI image and now I'm gonna set this thumbnail image in my document every time I close so when it close I'm just gonna make another snapshot of it so let's go do that to my controller here's where I close right after I save I'm gonna say that my documents thumbnail equals my emoji art view snapshotted okay so a snapshot is a little var that I wrote I put it in utilities you can go look at it's only three or four lines of code that just takes the view and snapshots it grabs it as a UI image okay and I'm only gonna do this by the way again if my documents emoji art is not nil because I don't a snapshot a blank document but what I should do here is do this snapshot and then if it's if this thing is is nil I should come up with some other nice thumbnail for it okay but I'm not doing that okay so let's make sure it rebuilds everything here okay so let's run again go over here see what this looks like okay it actually ran even though it said it had an error there but it did it did run successfully all right so let's open one of our documents okay remember we set our thumbnails when we close so here's one let's go ahead and close it and look we get this beautiful thumbnail of it how about this other one over here this guy okay let's close that one and this even works on our cloud drive there might be a little delayed on our Cloud Drive because it has to upload it but let's try see how fast that's pretty quick Network right here I don't know if you could see in our cloud drive it actually had the little cloud symbol there briefly as it was downloading it back from the cloud is kind of cool and this UI that you see here is all the full files UI so not only can you do things like I did before will you check the info but you can move it like I could move this from my iCloud back to my local device or copy here I guess and it's asking here if I want to keep both or replace it because it's both they're both called untitled so I'll keep both so now if I go back to my iPad here now I have three items okay including this one here and again sometimes you get a delay when you move things from iCloud getting the thumbnails because the thumbnails can be kind of big at times and so slogging them around can take a little bit of time here and there you can also rename your files so you know this is Apple in the sky so let's rename it was to call it sky Apple okay so you can rename your files all that stuff and the user can do it in here without having to go over to the files app to do that okay I have a couple minutes left so I'm going to show you one other thing which is running this on iPhone okay so let's go run this on the iPhone it's gonna go here run it in the simulator iPhone 10 let's see what this looks like an iPhone 10 so this whole document Browse view browser thing it all works just as well on the iPhone as it does on the iPad there's only a couple of things we have to think about when we try and make this app work on the iPhones you'll see here once this gets fired up okay so there it is see you can look we can look on iCloud drive here we can even see that document the document that we've created before on iCloud Drive and and open it we can open stuff off of iCloud Drive so I can open it now an iPhone I'd really like to still be able to drag some Mochis in and work on this document right one thing I can't do though is create a new document do you see why because on iphone you can't drag from Safari - dragon - dragon new things so it's really misleading that it says create document here because if I hit create document it can't I can't really create an actual document because I can't drag anything in so I really don't want it to say create document on iphone the other thing is I want my collection view to work ah you can't drag okay I'm trying to hope push down drag why just drag not work well drag doesn't work because collection view by default on iPhone does not allow dragging okay but we can turn it on so let's go fix both those things in our code we're gonna fix the problem with the misleading create by just this part here where we go and create the template I'm just not gonna do that on iPhone so I'm gonna that's gonna leave this to be false let's not do it so how do I check my code to see if I'm on an iPad and you do that this way you say if you I device current that's my current device has a user in user it err user interface idiom okay of dot pad okay and the other option is dot phone so I'm only going to do this template thing which is the only thing that can set this to true on the iPad so I'm never gonna have create document on an iPhone that's good now what about the dragging of the collection view well that's in my controller I'm gonna go down here to where I create my collection view okay this is my collection view outlet setter here and I'm gonna set this thing in collection view called drag interaction enabled now this is true by default on iPad and false by default on iPhone but if I said to true everywhere now it will make it so I can drag in my collection view on the iPhone as well so when we go here we won't see the create button and we also will be able to work on our document okay so let's open this document right here here it is now look I can drag drag around in my collection view and I can also pull things out of here and into my picture okay I can even mark it as save and done and if I went back to my iPad I'd be able to see it over there okay so the only two things I'm gonna do post lecture here that you're not be able to watch me do is the delegation thing so that we don't have to have that Save button anymore cuz we hate that and also adding the new type emoji art okay which really is only two things I'm going to change I'm going to add the mode thing in that settings that I was telling about and then I'm going to change this right here my empty template to be untitled emoji art that's the only change I'm going to make to make it be using emoji art documents instead of JSON okay alright that is it I will see you all next Monday for more please visit us at stanford.edu
Info
Channel: Jakub Moravčík
Views: 788
Rating: undefined out of 5
Keywords: stanford, university, cs193p, iphone, application, development, ios 11, ios, swift 4, swift, persistence, tutorial, course, documents, paul, hegarty, json, uidocument, store
Id: -PkKWknQmcA
Channel Id: undefined
Length: 79min 59sec (4799 seconds)
Published: Wed Dec 20 2017
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.