字幕表 動画を再生する 英語字幕をプリント Stanford University. Okay, well welcome to Stanford CS193p, Winter of 2015. This is lecture number five. And, today we're gonna finish up what were talking about last time. And talk a little bit about Objective-C compatibility, because, of course iOS was originally written in an entirely different language. And so there's a little bit of bridging between the Swift world and the old world. And we're gonna talk about an example of using any object which is property lists. And I'm gonna do a kind of a brief demo even, showing you that. Then we're gonna move onto a completely new topic, which is views. So, views on how we draw, and how we handle touch input. In our UI and so we're gonna go over that, and I'll be having a demo for that as well. So, I'm gonna blast through these slides pretty quick. As usual, the demonstration is probably a little more elucidating then some of the slides, cuz when you see it in action, it's a lot easier to understand. Okay. So, Objective-C compatibility, so, virtually all the iOS API, this API that was written over the last, however many years, in Objective-C, is available from Swift. And you can't even tell the difference, okay? It's just kind of, automatically made available. And, when they designed Swift, they went to a lot of trouble to make sure that it would, could be done in a very compatible way. So, that all of the iOS API, would work, just fine in Swift. There's few special data types though, that they've gone to special care to bridge between the two languages, and this makes using iOS API from Objective-C, much easier in Swift, and so, I'm gonna talk briefly about those. One is NSString. That is the old way that string were represented, in iOS, and that is bridged interchangeably to Swift's string. You can't really even tell the difference. If you have a method that takes an NSString, you can pass a Swift string in there, and vice-versa. Okay, they're just automatically treated if they were the same thing, even though they are quite different things. String in Swift is not even a class. Okay, its just a struct. So, they've done some miraculous work to bridge these things. NSArray, which is the old array, is bridged to array of any object. Okay, so any time you see, an array of any object in an iOS API, it's because it was an NSArray before, okay? Then NSDictionary is an interesting one, it's bridged to dictionary where the keys have to be subclasses of NSObject, and the values are any object, okay? Now, you might think, that's gonna be a problem, and I'll explain why that's not in a moment. And then of course, Int and Float, Double, Bool, they are all bridged to NSNumber. We talked briefly about NSNumber, we talked about the NSNumber format and all that. So, NSNumber was the old Objective-C object that just meant, any kind of numeric value. And, so anything that used to take an NSNumber, you can pass a double, or float or int in there, and it'll just work. Of course, coming back the other way isn't automatic, because it doesn't really know necessarily what you want. But you can use the methods like double value or int value, like we use double value, in the calculator. And of course, int and float and double are also bridged to the C types int, float, and double. So, you have an API that takes an int, and hold a C int. It'll be bridged to take capital I Swift Int. So, this stuff, all just works completely automatically. And you don't ever have to do anything. And it just works. However, if you wanna be explicit, about the type, you can cast, okay? So, it is perfectly legal to cast a Swift string to an NSString, and it will always work, so you don't need as? Okay, it's all a hundred percent guaranteed cast. And then once you do that, you have an NSString instead of a string, and so you can send it messages that are in NSString. Although you wanna be careful with some of them, like length, is an NSString method, that doesn't exist on string. It doesn't exist on String for a reason. Because, we talked about this before, you know, the length of a Unicode string, can vary, compared to the number of glifs you'll see on screen, and the new Swift string deals with that, and the old NSString doesn't really deal with that properly. So, you gotta be careful, when you start calling NSString methods that, you know, there's not, you wanna look for a string equivalent, and use that if you can, because it's newer, and it does thinks a little more accurately. But NSArray is the same thing, you can cast from an array, that you have in Swift, to an NSArray, and then you can call them methods in NSArray. Like components joined by string, which is kinda cool, it takes all the components in the array, sends them description, takes those descriptions and joins them by the string you pass as an argument. This is the same as the join method in Swift's string. Okay, so, you can look at the documentation for string and, NSString and NSArray, but pretty much all the things you can do there, or most of them anyway, are available in the Swift versions. But again, if you're passing them back and forth, it's all automagic, so you'd say. Now, you might get a little concerned about dictionary, because dictionary, the key has to be an NSObject. And of course, we know that string, and array, and dictionary in Swift, are not even objects, okay? They're not any object, or they're, and they're not an NSObject for sure. But you can still pass them anywhere you wanna pass in any object, or a subclass of NSObject, because they are bridged to classes that inherit from NSObject, because NSString, NSArray, and NSDictionary all inherit from NSObject. So, that means strings, Swift strings, can be the keys in a dictionary, an NSDictionary, even though it requires NSObject, okay? And of course, all three of them can be values, because, even though they're not really objects, they are structs, they are bridged to things that can be. Okay? So, it is okay to pass a string or an array to any object. You won't even notice this bridge isn't bridging 99% of the time. It just happens automatically. But I just wanted you to know that's going on, so you don't get kinda confused when you start seeing NSString, NSArray, what's going on, okay? They're just being automatically bridged for you. All right. So, we talked about any object last time, and now I'm gonna talk about a use of any object, which is called property list. So, property list is not a type or anything like that, it's just a term that we use. And the definition of that term is, it's in any object, a property list is any object, that is known to be, behind the scenes, one of those six classes. NSString, an array, dictionary, number, data and date. Or bridged too with Swift, okay? So, why do we define this property list thing? Its in any object. Its kind of unwieldy, because you have to do a lot, a fair amount of casting, ising and asing, cuz any object, of course, to use it, we have to kinda cast it. And so, why do we have this thing? Two reasons really. One, property list is used to pass data around blind. It's like a cookie, right? In a browser. It's kind of this just bundle of data, that only the creator of it knows how to interpret it, because only they know what strings, arrays, dictionaries, and stuff are in there. But to everyone else it, just looks like any object, so they don't know what it is. So, all they can do, is pass it around to other things. So, it's good for blind data passing, the other thing is, a property list can be used as generic data structures, okay? Since it's got arrays, and dictionaries, and numbers, and dates, and all that in there. You can turn a data structure, like your r-ops stack, in the calculator brain, it has op enums in there, that's not a generic data structure, but we can turn it into a generic data structure, for example, and then do things with it like write it out to disk, or send it over the network, or things like that. So, those are the two main reasons we use property list. And, a really good use of property list in iOS is NSUserDefaults. So, NSUserDefaults is like a really tiny little database, and it only knows how to store property lists. Okay? And it's really for things like settings, and preferences, stuff like that. You would never, it's not high performance, you would never use it for big things like images or anything like that, just property lists, you know, dates and strings and doubles, and things like that. It can store and retrieve any property list, and it just stores it like a dictionary, as if the NSUserDefaults thing itself is a dictionary. And, it can store the whole property list, like set object for key, that first method you see there. And, repeat, retrieve all property list, or, it can just do little tiny pieces of property list, like it has a method set double, that will just set a double for a certain key. Okay? So, it's like a dictionary in it's key value, but it only stores property list. And, the big thing about the way it stores them, is that it persists when your app is gone, okay? So, you know, normally, a dictionary is stored in the heap. As soon as your app quits, it's gone. But this, stays around, so that when your app launches the next time, all the data's still there. So, that's why it's kind of like a database, but it's very small, okay? For preference and settings. Here's how you use NSUserDefaults. You use this type method in NSUserDefaults called standardUserDefaults. This gives you an instance of an NSUserDefaults. You're always gonna use the same instances like a shared instance. You'll always to use the same one. And then you just send it messages like, you know, set object for keys, store this property list, and get object for key to get it back. Now, the changes you make in there, are automatically saved, but, there is a method called synchronized, which is kinda like save, which can force it, to save out to disc. Why do you ever need synchronized when it auto saves? Well, in auto save, when things happen like you app stops being the front most app, the user switched to another app. So, your app is still there, but it switched to the background. It'll save then. So, it won't always save when you want, and especially when you're debugging, okay? When you hit stop in the debugger, it doesn't save, okay? And so, you probably wanna throw some synchronizes in there, to save this thing out, especially when you're debugging. It's not really that expensive to synchronize, especially if there's not much data in there, which there shouldn't be, because it's small. So, it can't hurt too much to throw them in there. Okay?