 Hi, my name is Nathan Walker. Thank you for joining us all here and celebrating JavaScript, a language we all hold so dear. I'm an open source contributor largely around JavaScript. I also serve on the Technical Steering Committee for NativeScript, which is an open source framework allowing you to code platform APIs directly from JavaScript. I'm also co-founder of InStudio, which is a software services company. I'd like to take a moment and talk briefly about what NativeScript is for those who are not as familiar before we embark on a fun journey of a mobile app user. What we're referring to with platform APIs is the native language that is used on that particular device platform, Objective-C and Swift being used on iOS and macOS, and Java and Kotlin, for example, being used on Android. What we see here in this example is a snippet of Objective-C code that we can write using NativeScript with familiar JavaScript syntax. This is all without leaving your JavaScript IDE and allows you to go to source documentation without learning a whole new set of APIs just to get at that particular platform API. You can just use what you find in source documentation directly in your JavaScript development. Another example here showing a Java class which extends, for example, Java-laying object. And we can also construct one of these using JavaScript semantics and we could pass it an array, a typical JavaScript array, to that actual method that was in that Java class. Again, this is all occurring in real time in front of you in your JavaScript development. To show one last example using Java, we can again use very standard Java APIs that have been around for years like Java IO file and constructing a file class and using those APIs directly again in our JavaScript development. What this leads to is a number of interesting development scenarios. For example, because you have full access to the platform APIs, you obviously have access to the platform view language as well. NativeScript provides a core library that gives a pretty concise view markup language on top of this as well. If we look at NativeScript's core repo here and we dive into the source code, you'll find familiar classes for those particular platforms at their base. For example, every layout container on iOS is actually a UI view like you would typically do with iOS development. What this provides for is rich platform development and you can do this in all sorts of creative endeavors when it comes to building an application for that particular device. This is an example showing all sorts of APIs being engaged with for the iOS platform and developing a pretty dynamic UI. But what if you're not familiar with platform view development and your particular development style is with, of course, HTML in the DOM? This is what the great team at Ionic has developed with Ionic Framework. These are really high quality toolkits that you can build mobile UIs using the familiar DOM. This lets you build these controls fully with HTML and a whole framework behind this to deal with different paradigms on that particular device UI. The Ionic team has also developed Capacitor.js, which is the mobile runtime that allows you to take these web view developments and deploy them onto these devices. NativeScript also works with Capacitor. The NativeScript for Capacitor integration allows you to use NativeScript directly from Ionic components and integrate and do all sorts of creative platform development directly from your Ionic code base. Instead of me explaining this integration, let's sit back, relax, and watch an entertaining journey through time of how a mobile app user encounters struggles and how this particular integration can help. Enjoy. Hi there. Where to? Downtown Austin, please. Of course. I know that one. Book of Norman, right? It's by the old South Park guys. What were their names? Yeah, yeah. Let me check. Why didn't you stop the music? It's the app. Now I have to download the file again and it's 1.21 gigabytes too. Tell you what, that's gonna take some getting used to. You know, see, I'm super excited about this app we're building. I'm already having a ton of fun with Angular and Capacitor 3. And yesterday I started prototyping a few of the key features, but I'm running into a little bit of trouble. Like I tried a few available video plugins. I'm struggling to get that, you know, picture-in-picture behavior, you know? Like when you switch apps and you get that little tiny box of streaming video, I can't quite pull that off. You have any ideas? Yeah, you can use the descriptive create all on video player. Hang on, you mean that small community native view framework thing that died a long time ago? I wanna create this app with Angular and Capacitor 3.0. See? Well, native script is not just for native view handling. It can actually be used with Capacitor and I can show you how. Really? Okay, so let's start with installing our native script, Capacitor plugin. Okay, I didn't realize this, this is just an NPM package we can install. Yeah. Nice. So it's done. Okay, so this is what you get after you install the package. A nice little helper. So this is like little helpers we can sprinkle into our Ionic capacitor app. Yes. Okay. Next, we will create our Angular component, which will post our video player code. This is our Angular component we just generated. And here is the definition for our helpers there. Oh, interesting. So these APIs are accessible to us in Capacitor that we create here? Exactly. So now that's why you start wiring up some code. So here we would import the newly created index custom API that we'll be using in Capacitor. This is what exposes that API for us to use, I guess. Yes. Okay. So here's our first helper to create the video player. And we'll use the AV player view controller for Apple Docs. It also supports your pittier and pittier, which you would like. I see. So you think that creating this player here is gonna allow us to engage with that picture and picture behavior I'm after better? Yes, it will. Okay. So now I see you can get some nice IntelliSense and we will choose to use the new method on the controller. It's really a convenience method which helps us to create a native instance of that controller. So now back to the component, the Angular component. You see we use the helper that we created from the native object. Got it. You know, this is pretty interesting, OC. I was wondering the other day, like OC Fortune, that's a really awesome name at that. And I was kind of curious, like where the fortune comes from? Like did your family have some fortune in the past? Like what's the history there? Well, I'd really like to know about that fortune, but I'm just from the Caribbean, Trinidad to be able to be exact. Some would know it as the city home of Soka. Also, we have the greatest show on it, which is called Carnival. And we are also the creators of the steel drum. Ah, boy, I love a steel drum. Good stuff. So now let's go on to set up that audio session. So again, you're just kind of following the platform documentation to create this video player. And this audio session is just something that is important, apparently according to the docs for us to do to set this player up. Yes, it is. Got it. So along with setting up the audio session, you would also need to set the category as well. Good documents. So let's grab that from here. So you can see we get some nice help from all the intelligence. So we wrap that up in a nice try catch. So it would show us any errors we made or the player running to any problems. By the way, Nathan, you ever Google your name? I'm sorry, Google my name? No, I hope I'm not that vain. Well, if you do a quick search, you would find a hockey player. A hockey player? Yeah, no. I wish I knew how to play hockey. That's not me. So on to the playback behavior. You'd need to set up a player. Let's create that player instance. Again, you're using the convenience method new. I see you don't get any any intelligence right there off that player controller. Yeah, we just needed to set the instance. There it is. Okay, so here we would use a helper that the plugin gives us to grab the currently presenting view controller. Interesting. So this is an API that comes from NaiveScript Capacitor and this gives us access to the view controller that is hosting our Ionic app on iOS in this case. Is that right? Yeah, that's correct. So here we would add that player view controller to the root controller. Oh, see, I'm kind of confused here. So you're adding it to our Capacitor app, but I'm kind of confused. Where is it going to end up on screen? I mean, you're just adding these things to the Capacitor app. I mean, we got to put it somewhere on the screen. We'll add it here now by setting the player controller views frame. Oh. So we can use the device metrics or screen metrics. So we'll grab the screen size for me. We would use the width and create a nice little insight. I see. You're sort of using exactly the same methodology you would on this particular platform to position this player on screen. Yeah. OK. So I have a nice little size. And that's it. That's what we're positioning. So now we're going to set up the URL that we will need to play. Here we will be using the URL and password to our new player. I think I follow where you're going. You're creating yet another helper API so we can dynamically control the URL of our playing video. Is it my following you, right? Yes. You're on point. OK. So after we create that new player, which would have our URL, and we assign it to the controller, then we hit play. So now back to the component. We will set up an input that we can grab the URL from, that we can feed to our custom API. Now that's pretty interesting. So here we have an Angular Ionic component where you define the URL input that can then be passed dynamically to a native video streaming player that we just coded on the fly. And that will play whatever URL we pass to it. Is that correct? Yeah, that's correct. You are following pretty good. Oh, see, this is huge. Hey, hi there. Where to? Downtown Austin, please. Of course. Turn it off. Turn it off. Hey, I know that one. Book of Mormon, right? It's by those South Park guys. What were their names? Yeah, yeah. Let me check. Trey Parker and Matt Stone. Right. Love those guys. I kind of wish I didn't have to leave the app to get more info. You know, see, I was thinking, I'm following what you're doing here. It's pretty straightforward. I'm going to add an onEvent and removeEvent API. And I want to create a little event bus system where we can shuttle some events around what we're doing. And I feel like we can do some neat interactions with our capacitor app if we can get events off of this. And since we're using Angular, I'm just going to use RXJS to set this up. So just a simple event bus around a subject. And I'll track the callbacks that could be wired in from our Angular component and just emit that out of our subject here. And I think this will give us what we need. Yeah. Well, I have an idea. You can use the player delegate, actually. But it makes an event when profiles started or it was ended. I see. Interesting. Okay. So this delegate thing is the ability to sort of wire in some events that you get off this player. And you're going to try to set up one of these delegates here. Yes, exactly. Okay. So now this is interesting. What are you doing with this native class thing? I've never seen that before. So this native class decorator is really a helper. So we can generate the native side using what's given to us from TypeScript. Got it. And what about this Objective-C protocols? That sounds kind of wild. What's going on there? Okay. So with that, it gives the runtime the information that's needed for that class. So basically it tells the runtime that this class has these protocols. So it should follow these protocols from Objective-C. Got it. Okay. Now it'd be really neat if like you could actually get IntelliSense on what comes from these protocols. Like is there a way to do that? Yeah, you'll get that by using the implements. Ah, now I'm familiar with implements just in TypeScript. So it works like that just the same way? More or less, yes. Interesting. Oh, I see some IntelliSense on some methods there. Okay. So now we can use your event bus and feed it some events. Okay. Now I'm following you. So these events are going to be called back from our player and we're going to use the event bus system that I set up to shuttle those events back out. So we should be able to react to those in Capacitor. Yeah, exactly. Got it. Got it. Okay. Now you're kind of just setting up the ability to kind of connect that delegate to our player, I guess. Yeah. So the controller would feed it the delegate that we just created. Got it. So back to the component we would use the events we created. Oh, this is pretty sweet. So this is the on event API that I added here. And we can now wire into events that are coming off of anything that we created over there. And this will give us some good reaction points in the DOM. So we could perhaps maybe we could have a scrolling area of text that actually scrolls up and takes the whole screen when the video pops out in picture-in-picture. I assume we could probably do that sort of thing. Yeah, you can do that. Yeah, that sounds good. Sweet. Turn it off. Turn it off. Oh, if you like that one, you're going to like this one. Anastasia. Another good one. Ah, what happened? The battery died. Now I lost my place in the video too. Hey, you know, I was just thinking like what happens if a user is watching this musical and right at the best moment of the musical, their phone dies like unexpectedly? Well, I have an idea. We can wire up a event for that. So we don't know when the battery is watching. Oh, good idea. Yeah, so let's set up the API here. OK, so another helper method here to listen to the battery level change. Now we'll use normally the script capacitor docs. There's a nice little API to register a broadcast receiver, which we would use to get the events. OK, so here you set up the callback and we would grab a few properties that we can use to limit 8%. Ah, got it. And then I guess when it's toggled off, you just, you're just unregistering that. Yeah, you don't want those lying around. Got it. Well, I could probably do iOS. I know that in the docs it mentions using the current device battery, I think monitoring enabled allows me to turn it on and off. And from there, I think I can use just a standard iOS observer to basically observe a system notification when the battery level changes. I think that's straightforward enough and will probably give us the notice that we need. So I can probably use this. Looks like we got IntelliSense on it. There's a battery level did change notification we can wire into. And these other arguments I don't think we care about. We can just get our callback and emit when that occurs. So we get sort of the same thing, a percentage of battery level. Yeah. And I guess if I track, if I track that observation, I can just remove it when we turn it off. Yeah. So back to our component, our Angular component. We were to wire up that list now. Okay. Well, that's pretty sweet. So we can wire in the battery level listener right there in the Angular component and just notify the user that their phone is about to die. You can do that. And you can also see the position. What you think. Nice. Oh, if you like that one, you're going to like this one. Ah, Anastasia. Another good one. Life is one of the choices I mentioned. What happened? Well, the battery died, but it's okay because it saved my place so I can resume it whenever I charge my phone. Say, do you have a phone charger? No need. We've arrived at your destination. Open JS World 2022. Thanks, doc.