Bringing your React Web App to native with Capacitor

Workshop from:
React Summit
React Summit 2022

So, you have a killer React app you've built and want to take it from your web browser to the App Store. Sure, there are a lot of options here, but most will require you to maintain separate apps for each platform. You want your codebase to be as close as possible across Web, Android, and iOS. Thankfully, with Capacitor, you can take your existing web app and quickly create native iOS and Android apps for distribution on your favorite App Store!

This workshop is aimed at intermediate developers that have an existing React application, or are interested in mobile development with React. We will go over:

What is Capacitor

How does it compare to other cross-platform solutions

Using Capacitor to build a native application using your existing web code

Tidying up our application for distribution on mobile app stores with naming conventions, icons, splashscreens and more.


Okay, so this Workshop is bringing your react web app to Native with capacitor. Like as I said, my name is Mike Cardington. I work on this technology. I work at a company called ionic. We do cool stuff with not only web technology but native as well. So we we know a thing or two about Bringing web apps to Native and bringing some web goodness to Native as well. Quick little notice on some housekeeping this is being recorded. You'll be able to watch any replay at a later point in time. I'll try to post all of the slides though. I don't think the slides are going to be too applicable at a later point in time most of the conversation that I'll be that we'll be having here. We'll be the most important part. So I'll try to post what I can afterwards but don't don't worry too much about slides and everything. As I said post your questions, there's a chat feature. We'll we'll use that also uses Discord if we if you that's where you feel comfortable. I'll try to meet you where you are versus forcing you to use any one particular thing. So with that out of the way seem to get a little comp point in tendies seven. So I want to First diving to this concept because it's going to be the central point for everything. We're going to cover today. And it's this idea of cross-platform cross-platform development is something that is not uncommon. It's done in almost every software. That specialty if we think about games video games. You rarely see people writing a game once for PlayStation once for Xbox and then again for PC. There's typically some sort of tool that they are using to build their games and then have that essentially be able to run on all of the consoles the desktop environments and all they really need to worry about is building their games using these tools and to be able to take advantage of this cross platform. So this is a very well tested approach to building a product into build anything. We're just going to look at it in the context of building an app And taking your existing web apps to be able to Port them to these different platforms. What we're trying to figure out is how can we reduce having to learn new things? Reduce having to ship or create more code that is specific to a different platform. And reduce the time it takes for us to actually ship everything because having all of the different Technologies choices available to us. It's an amazing thing, but we're spending a lot of our time having to focus on Learning a particular tool and then we never get to ship. It's kind of All or Nothing. So reduce our our overall knowledge that we need to know reduce the code that we need to write and then reduce the amount of time it takes for us to ship something. so when comparing different Technologies, we we have to look at it in terms of abstract. Um too often or not. We get into a situation where folks like to say x is better than why for these three reasons, I mean think about how many How many verses articles exist out there? React native versus flutter flutter versus the web all these different technology kind of comparisons are doing a disservice to themselves because they are trying to go point for point with the thing that they are comparing themselves against doesn't always work out that way thinking of it as terms of strip levels of abstractions to me makes a little bit more sense. So we're going to look at a few of them the way I tend to think of this is how far removed from a given Target is our technology choice. So here on the left. We have a pure web development environment. You are not even focused on mobile or like native mobile your only focus on building a good responsive web experience. On the other side we have pure native where we don't care about the web. We are just focused on building dedicated native app for each platform and we have honey tea plenty of teams that can focus on that and work in that environment. so start off with the pure website and I'm gonna look at this one first chances are if you've been a developer for any or at least five years, you might have heard of this project. It's called Cordova. It was probably one of the first projects to promote this right once Run Anywhere Mantra where they gave you essentially a polyfill or native device features. They were a bunch of developers that want to build web apps, but the web at the time was not really a good platform to develop for it was missing. Several key features that needed devices had right away. So they decided to build this technology to expose these native features through JavaScript and then let developers go ahead and wrap their web app in this runtime. And then provide access to those features by extending built-in web platform features. For instance if there was a g the there was an old geolocation specification. They wrap their own geolocation API on top of that. Of that old specification. So the extended a lot of the built-in features that ship at the browser to supplement their own native runtime features. So they they started off using this approach realizing that certain apis don't really map well to built-ins So eventually they did need to go ahead and create their own Global apis and they built up on top of the Navigator object for whatever reason. And inside of this they were able to build out essentially objects that had all of the functionalities for the core plugins. So one of the first one that they had was this camera plug-in and then they created a way to take a picture or present a native camera activity to your users directly from your JavaScript. So they have this Navigator DOT camera dot get pitcher. It had an on success and on fail callback. And then there was a third parameter where they allowed you to set all of the different options for this execution. If the camera call was successful you'd get the image data back. and if it was if it failed for whatever reason you get a an error message return back to you. work worked well Now this approach of using Navigator and having everything tied to that fails right away. When you realize you need to include Cordova with everything to get this to work there. What there is no built-in camera API currently with the web. Although that would be a fantastic new feature. So it's Autumn automatically not as cross-platform because if you don't include it in your web browser, or if you try to run this in your web browser right now, it would it would fail because there is no way to mock camera with something that exists in the browser. So this is only available when you're essentially targeting. IOS or Android? So the camera was one API, but there was this huge ecosystem that came out of Cordova where they have things for Firebase they had plugins for Blanking our names Century PayPal. They had a lot of success getting people to build plugins. And they themselves also shipped a good collection. I believe like 12 to 14 core apis that they felt were essential to a device. So geolocation camera file system access splash screen controls status bar controls all of those types of things. they didn't really have a package manager Cordova predates and PM, which is pretty Pretty hard to imagine an environment where we did not have mpm. And this was also before Bauer for the people who remember what Bower was and they basically had these custom built built. scripts that they would run anytime you wanted to trigger a release which were not that great they had a lot of learning curves because they were pretty head of the time for 2010 so this whole idea was to keep the web was to polyfill the web until the browser finally added those features. It's 2022 some of these features silicone exists into the brow in the browser at the moment. So it's pretty fair to say that their target. What their target goal was a pretty unsuccessful? they also didn't want you as a developer to ever need to open up a native IDE, which I don't know why a native IDE is actually pretty a pretty good tool for configuring these native projects. So going back to that custom scripts thing if you wanted to set your profiles for signing and releasing the app. It was all it all had to be done through pretty obscure script tags are script tasks and passing in different options, which not ideal. But they took this even further and made it that way the native projects were things that got destroyed and not committed to Version Control. So if you and a coworker are trying to work on the same app. You set a permission on your machine. They set a permission on their machine. There's no way those permissions ever being like shared. There's not constantly having to be reset. So not not ideal. Okay, so that's the very beginning of cross-platform that was going on for a little while. People were pretty happy with it. sure, there were some pain points, but for the most part there was the only project in the space then came something called react native and several other, you know, well unquote compile the native where their main goal was to say Hey you right in this tool and it will give you up here native app afterwards. So I put this kind of cheekily saying that learn once right anywhere as he kind of initial goal of react native their idea was that trying to do right once Run Anywhere was never going to work. So rather than have that give you an abstraction where you could learn one API or one style of programming unless you write for all these different platforms. they promised that would be a truly native app, which It's not necessarily the case. It's not too different from Cordova and they build abstractions around native controls. They did provide a nice standard Library. So to speak around these native apis. but it was basically put upon the community to add more features than the core team actually wanted or any core team from various projects. So in a sense when you are building and this is just a simplification for react native when you're building a react native app. You essentially have you know your app over here in this blue box being ran inside a JavaScript runtime. as could be V8 Dash core something else, but essentially that is running your JavaScript and that runtime will communicate through a bridge layer. Anytime that bridge layer tries to access device features. It's going to proxy out to the actual. device features get the results serialize that to Json and then return that to the JavaScript runtime. And that is going to be sent back to your app. As the UI gets evaluated the bridge layer is also going to communicate to be native runtime and render out all the controls essentially on the fly. So all of the UI elements the buttons cards tab navigation as all getting rendered on the Fly internally via react native. And this is actually a pretty similar infrastructure to few other projects. It's not specific to react native. So don't assume that there's a very similar architecture to Cordova here. The only difference is that instead of a JavaScript runtime. It's a full browser ecosystem and we separate out the Rendering process and just use the browser to render. So these are very similar architectures. My and this is a bit of my own personal opinion towards it. We're kind of breaks down is having this idea of different having to learn a new syntax. That isn't essentially the same stuff that you've learned for web development. Having to learn how to redo H1s HQ paragraph tags anchor tags. is kind of kind of frustrating I get why they did that, but it is yet another thing to learn. If you have an existing web app where you are trying to get that into the native runtime or the native stores. You're unfortunately going to need to rewrite that app to support this react native runtime. Some people will do that and they'll say it's okay, but it's still just a frustrating feeling and then finally if there's a third live third party library that you really really like if it does not support react native out of the box, you can't use it. So I have a my favorite one of my favorite libraries out. There is Bill JS, which is a rich text editor. You can't use that in react native because of how it's built and how it works. You have to find one that's specific to react native in order to get it to work in a reacting app. Which seems Seems not right in my opinion. Yeah, I mentioned it earlier but the idea that it's really native is a bit misleading architecturally. It is still running JavaScript controls are rendered on the Fly. There's essentially a custom rendering agent this last point for folks who are interested in flutter. This is something that you do need to deal with is that the rendering is not actually rendering native controls. It's rendering things in the loosest sense. On a canvas and then you're just interacting and re-implementing all of the Native interactions. Take that for what it's worth. It is just the facts. So moving on what are the other options here? Ideally, we want something that kind of bridges the native development life cycle, but also still very much in this web developer, you know kind of mentality where I am just writing HTML CSS and JavaScript I can bring not only react but any framework into into my toolkit and I can just ship whatever I want. So that is what we'll focus on today and that is capacitor. so in a runtime in a nutshell capacitor is a native runtime and a JavaScript library. It is at first a way for you to import packages that provide access to the native device features. So similar to Cordova in that sense. Except that each package itself allows it to wrap various different apis and we'll look at how that works. The apis that you as a developer actually interfaced with are streamlines that way you have this one particular way of accessing the file system and then the packages that you will interact with know how to send those options and call certain methods that fit on say iOS or Android. And when you want to include a new package, it's basically just pulling that in from the Native package managers inside of the respective projects. So if I install say our file system API It's an npm install for me, but behind the scenes. It's using Coco pods to vegetative dependencies for iOS using Android varies for Android. So the package management story here and how the code gets from your node modules to the native project feels at home for those respective platforms. So let's take a look at the architecture because I think this is actually pretty important. So we have our web app here in the blue box again. And it gets rendered inside of a a native web view. So this native web view is basically just an optimized version of Chrome Safari, what have you Without any of the browser UI elements in there. When you go ahead and make your call from your web app through capacitors API. That native web view is going to be able to hear that call or at least know that something's something inside of it is trying to call a capacitor API. So it'll get the information that you're trying to call for the try certain device that you're trying to call. And it will send that to the bridge layer the bridge layer will then proxy out to the native features whether they are operating system level features or Hardware features serialize the results return it back get sent it to the native web View and then that will get returned to your JavaScript code. So architecturally, this is very similar to how react native works. With the exception that we are rendering our own UI. So if you have a UI library or if you have your own. design system in place You can bring that to a capacitor project. And still have the same experience between your website you're native app, and you need via WhatsApp and your nana native Android app. So great experience all around. How this is different is that as I said, you could reuse your existing web apps and your existing web skills. This includes third party libraries Frameworks. Again, we're looking at it with react today, but this is a framework independent. So if down the road you work on a project and you have to use something like spelled or solid or View and angular you could use it with any of those tools. It does not care. It is mostly just JavaScript. The runtime loads instantly. So as your app is booting up. It is essentially a bill of able to call native apis right away. So there is no slowness as it waits for everything to connect you are able to call location data as soon as you have starts up, which is really really nice not something that was possible with Cordova. And can make your app really stand out. It's it's very drastic how fast it is. And as I said, it utilizes the best practices for native meaning that. We're not trying to introduce. Our own thing native has its own set of tools and resources. We're just going to use them and take advantage of the fact that those tools exist. So that's enough for like the slides enough for all of that. Let's bring up. Um, well we got a question. Does it produce a native app or a web app with mobile? Hardware OS features Yes to both. I know it's not really a great answer at the moment, but I'll show you more about why I think it's both and you can debate if you think it's it. I'm wrong. Let's go. Um to my terminal so I have an app over here. I'll just open this up in vs code. and I will change my color scheme real quick because I had a super bright and then I will also Yeah, and Pam runs starts start my terminal. So this is quite literally a blank react react app project and let's get this over here. And to some window management real quick. And just one more and I get a thumbs up if you can't thumbs up in the chat or can I get some indication in chat if you think that is a good? And yes index that yes. Next Step. Yes X. Okay. How's that? Look for a files font size too big not big enough. Look good anything. Okay. I saw thumbs up. So we're gonna assume that that is good. Awesome. Thank you all so I just created this app. You could create your own app with. Create react app if you want, I think it's MPX create react app in it. Don't quote me on that. But the idea is that this is nothing more than what the react. docs yes that you do you create a project you now have you now have all your files over here. You have an app dot TSX. I'm using typescript for this you you don't have to I just think it's probably the best way to do this stuff in 2022. And make sure that it all makes sense. It is in a type Safe Way. And we have our app here. It's letting up an image. We have some docs on the code we can. Probably get rid of this link tag. Everything is updating pretty well, and we're gonna focus on here for for most of this because I don't feel like I'm not trying to include so many opinions on how you build your app. I hope you have your own opinions on how to do that. I want to show off what you can do without having to Go through a lot of explainer on okay. Well, here's the UI library that we chose to use. So, um From here. We do want to install and set up capacitor for this project. Save again. Let's go back to our terminal and I'm just going to split keep the dev server running. And I'm going to start installing some dependencies. So the first one that we're going to need is suit and we install. Kip capacitor for And then at capacitor CLI. So their names are pretty obvious at capacitor core is the core runtime the core Library. And then at capacitor CLI is a very slim CLI that will go ahead and manage to create the native projects and manage the native dependencies. We're gonna go ahead and run this. It should only take a moment. They don't use too many dependencies. So it works out. And what those installed? We have a question cool. Um Stefan we'll get to your question in a moment. I just want to initialize this project first. To initialize a project once we have the capacitor CLI installed we can just run npx. cap And then a knit. so this is going to be our little walkthrough process of how we create a project. What should our app name be we can just say react. Summit this again. User friendly should be something that people would search for. The next part is this package ID. Now. The package ID is a pretty standard thing that happens in both IOS and Android if you have never done any of native development before It can be kind of confusing they tend to expect this reverse domain style, but there is no. You know practice for how this should work. So I'm some do come that I'm Hartington. Dot dot hopefully that works. And then you'll see that it creates this configuration file for US capacitive config.ts. And then it produces some ducts for how to get started and what to do next what we're going to walk through this all together. So we don't really need a reference of socks, but we'll keep them in the background. If anything goes awry which it shouldn't. So let's take a look at that capacitor config file. Our config file basically tells our tooling how to manage the project and manage handling all the different dependencies in the web code that we end up creating. So obviously we have the app ID in here, which is that reverse domain bundle ID. We have our app name which will be used and displayed on say our simulator or our real device. The web Durr is essentially where all of our JavaScript code gets built to. So for a react project. This is going to be build. If you do have a custom project structure or custom setup and you do not build to build. changes to whatever you want and then bundle web and runtime is just a default. If you are not using a bundler like webpack or Veet you can set this to true and it will include a script tag reference. We don't need to worry about that because we are using webpacking this case. From here. I do want to include one. Okay. So for some reason Zoom had captured my keyboard controls. All right. I hope that that is still recording. All right. Oh, what I'm going to do real quick is just this little little trick that react native. Our react does not provide out of the box. And that is this meta viewport tag, and I am terrible with remembering it. So I'm going to Grab it from an existing project wrong directory. And I'm going to copy. this viewport instead and go back to the S code. Where did I have it? Viewport or is that it? Yeah that a viewport. So essentially what I just did here. Because of devices that have a notch iPhone certain pixel devices Samsung devices. Now, we need this you port bit cover in there essentially tell the web runtime to use the full real estate. Otherwise, it would cut below the knife and this looks kind of weird. So we'll keep that in there and we'll save our project is still running in the web browser. And let's go ahead and start accessing our first Native feature. I'm gonna use geolocation first because that is a pretty familiar API because it exists in the browser right now and you can use the browser geolocation API instead. I want to show why you would use capacitor, but first we need to install it. so to install it we have all of the core apis split out into their own npm packages so we can install it by just saying npm install capacitor geolocation. The glocation plugin is only focused on geolocation and provides all the dependencies that you need for that. which are basically the appropriate iOS code and appropriate Android code and then it wraps the web geolocation for a web environment. So back in vs code. and with that installed Let's go to our app.tsx and Alyssa actually add some stuff in here to start calling the geocation. So first we're going to import from at capacitor geolocation and we are going to import the geolocation API. The geolocation API will hold all of the available methods for us. It's going to be able to provide all of the necessary permissions and let us manage those permissions internally. So let's go ahead and also import from capacitor core because there are some differences in how platforms manage location or manage permissions. We're going to import this core capacitor. Class and it will give us everything we need here. Now we also need to have believe. You can do it up here. We actually don't need to import react from reactive beliefs. We do need to import use use effect to be able to manage handling these permissions. So let's go ahead and create this use effect. And it's gonna have zero dependencies. So it's going to be acting like a a knit life cycle hook. And the use effect is going to be a sink. Which I don't know if that's actually recommended. I still do it because whatever Actually, we won't do it. We'll do we'll do we'll do things proper appropriately. so our way of managing permissions or getting all this stuff is we're going to want to have a request permission. Function which gets called when the app initially starts up or when this component initially renders because it's has zero dependencies should only call this use effect instance once and then we need a const request permission. It's going to be an async function and inside of this we could literally just call geolocation. Dot request permission so bad that's growing. This is literally just how it'll go ahead and try to request browser permission to get location. Let's say this first and see how this works. So nothing really happens. Let's open up the devtools. So I am using Safari. Comments to yourself about that but what we have here is that we have this unhandled promise rejection. So as I said the web handles permissions Not really. Well compared to iOS or Android. So there are going to be cases where you have some apis that behave slightly differently between the different platforms. It's not a total total totally big issue because you know the warning over here or error over here. It's just a simple like unhandled rejection, which we could reject and handle ourselves. So your app isn't going to crash completely if you do this, if you don't like seeing these unhandled promise rejections either. handled the rejection well, or you could do what I would do and just say if capacitor is native platform. Then bring this up to here. And it will only run if it's on a needed platform. So we're already having some nice experience here. We can do some quick runtime checks to see if the location if we are on a native platform. And if we are we should be able to request permission. Moving on below this we should get our location first. so we can have a new method called get autocomplete failing me get location Which will go ahead and try to get our location data. So let's just stub this out real quick. well I'll Center this real quick. So this get location function? This is simply just a way. This is an async function. Again. Everything in capacitor is asynchronous. So you're gonna be dealing with a lot of async away or promises if that's how you want to do things. In this case. I wanted to just use a single weight because I think it's a little bit easier. But we also could use promises. With in this get location. We want to have a variable and it's going to be a weight geocation that get current position. Now get current position is going to be essentially a one-time call behind the scenes in IOS and Android. It's going to spit up a single shot location call return that data and then clean up after itself. So it's going to manage the memory and the impact of this call for you without you having to do any cleanup. So we'll wait the results of this and store that in a lock variable. And we can see the different return values that we get. We get a set of coordinates. or if my cursive want to move or a timestamp. Timestamp could be nice. If you are doing some kind of location where you want to update your users. For instance. If you're doing a delivery app, you could use the timestamps informant your driver has left the building at so that's just such a time or your delivery person has the left it's certain time. Um, we want to get this current position and we want to also display inside of our app. So let's continue on at the top of our function and we're going to create some some State real quick. So we'll just use date. and we'll have location data and set location data. So with that we can say set location data. Is going to equal in or it's going to be function call and we'll have our longitude which is going to be lock that coordinates that longitude. And then we'll also have a Latitude which is going to be chords that. Or lock that chords dot let dude. Now I'm just gonna do some quick little lean-up typescript is going to be pretty mad at me and just give it in any. Provide the proper type for everything and actually let's look at what's on coordinates? So coordinates gives us a bunch of different things out of the box latitude longitude accuracy and then also altitude accuracy so it can return whether or not you are. at an elevation also inside of it. There are few optional lock that Rewards. things in here for instance we could have the heading we could have said altitude accuracy. It's only available on Native platforms. So it is optional it could be undefined. You're able to type around that in certain situations where it doesn't return to Value. So keep that in mind as you do things. Let's close that out. And then underneath our or inside of this paragraph tag. Actually, let's change the paragraph tag to a pre. And then inside of this will render Json that's stringify. Location data, and this is a really really fun little trick. On just how to indent all of this stuff in a readable fashion. I'm not going to go ahead and show it inside of safari because Safari doesn't actually mock my location. Not that I don't think you are all trustworthy. I just don't want my location being out there. I believe it's localhost 3000. And let's see what happens. So there you saw our location. so actually let's go ahead and manage this location will delete this because I want to show how the permission gets set up and this is all managed through the actual browser instance at this point. So when you are on the browser because there is no built-in permission model or permission setting that is come comparable to iOS or Android as you go and you try to request permission. It's going to use the like a just in time model. So we you can see here that in this promise for get current position. we have a timeout which what can be configured so that way you can wait a little bit longer, but if you don't Allow it within a certain amount of time. You get a rejected promise in this case. Let's allow it. And because the timeout happened we will just do a quick refresh and you can see that we have our location data pointing us to our mock location. So far so good. This is exactly what we want. This is just essentially the bare minimum. I said, I don't expect you all to have the iOS SDK or Android SDK setup, but I do want to add a native platform first to show how this can work. if you do want to go ahead and try to install the iOS SDK or Android SDK, we do have a lot of don't allow we do have some good docs over here and how to get started with this. And how to set up your environment to work with these native platforms. We're going to discuss skip over that definitely check it out. If you would like capacitor slash Docs. Drop these into the chat. Let's get we're gonna focus on us and assume that some of this is already set up. To like add a platform we can just run mpm install at capacitor. And then we have two platforms out of the box that we support obviously iOS and let's say IOS and Android And we're going to install those real quick. Now when? Do want to touch on one of the questions which was from Stefan comparing ionic Cordova versus ionic with capacitor. What is the performance difference was the difference in the plugins? If we use cordob Cordova plugins within capacitor. Is it slower than using a capacitor alternative plugin? so just make sure you should be able to unmute if you would like Stefan. I just want to make sure that I understand your question fully and it's context. Yeah. Okay. So for me it's important. The performance of Cordova comparing to the capacitor and why shall I switch my project from Cordova to capacitor? That's so this is my question. Yeah. So this is kind of jumping ahead a little bit. But we hope you have an answer. You can answer later if you yeah when we reach it up. Okay, I'll let's do that and then we can go. Okay evil Pride more details. Yep. Thanks. Oh, no problem. So we have installed the two platforms. I was an Android. let's go ahead and then call Cap add iOS that was split up the install and the add commands to two different things because you might have a Package install of iOS but you're not on a Mac and you are on a Windows that would fail but we still want you to be able to install the packages without any issues. So we split them out to two different things and it simplifies our Our our work that we need to do. So we'll see add an iOS project. You can see it's going to create this native xcode project 30 minutes milliseconds. It could not run the or it could not sink it to the the webassets to the native project because there is no bill directory and then we get this nice little dock on how to handle workflows. If you get lost the documentation is always going to be there. we can do the same thing for Android it'll do the same exact steps and produce the same exact output varying different times. So I'm going to show iOS first because that's where I'm most familiar, but we'll show Android afterwards. So let's go ahead and do a quick build. It's going to run react scripts and it's going to run our native build or our web build. And produce the JavaScript that we need to deploy to. iOS with that process done we can run MPX cap sync iOS now you can see it's going ahead it copied all the web assets, but it's also using this native dependency and I don't know how well you can see with the flashing. It's using this native Coco pods tool that iOS uses. So all of the dependencies get installed through Coco pods for IOS and Android libraries for Android and just keeps the tooling that we need to generate to a minimum and uses the existing ecosystem. Once we are done with that we can run npx cap open. IOS, and it will open up our native xcode workspace. Skip this a moments. Effects code is a little slow today. That's pretty normal xcode is somehow slower than you know any electron app that I've ever used which is gonna be really painful for Native app native desktop app enthusiasts. I'm going to select my device to be 13 Pro. I'm going to let it finish indexing all the files. You can see over here. We have a little bit of a file tree where we have all of the dependencies that our native project means the development versions and then the actual Frameworks and tools that get included with this here. You can see we have the capacitor. We have this capacitor Cordova. Up pod, which is our Bridge layer. So if you are someone who is a or has a Cordova app. And you just want to migrate over but you're not fully set on being able to replace everything capacitor can take your Cordova app and support that as well. We have a nice little bridge to the cork Cordova apis and a good selection of third party apis. I would do I would suggest so moving all your plugins to using capacitor ones. And we have our geolocation API, which let's go ahead and actually look at what this is doing. I just think this is fun. So we have our our pretty typical native code here. We are importing some plug-in versions some some nice data. We have all of the different methods and it's actually supporting all of the methods like get current position watch position giveaway a little secret to what we'll do later and then check permissions and request permissions. All of these are being done inside of our Swift Code. So Swift is a swift is a language if you've never never in it before we won't focus it too much on it, but you can see that we have this nice asynchronous way of getting the location. And managing all this for you. Same thing with watch position. We have this whole entire way of getting the current position and watching it as changes happen over time. So there's a bunch of data code native code in here. We also have our app. our app dot delegate the app delegate is probably something that you won't customize or you won't use too much. But if you are part of a team where there is a collaboration between web developers and a native developer via iOS or Android you can have them come in here and provide some overriding features for when your app starts a lot when it becomes active again after being in the background. Or when it does want to receive notifications, so all of this can be customized to your heart's content. The main storyboard storyboards. I the best way I can think of this to describe them are these are our kind of mock-ups and our ways of building up the structure of our app like by adding widgets in UI. We don't really need focus on it too much. We are first going to just try to run this and get everything to load up on a simulator. I'm going to run this from this little play button. It will go ahead and try to deploy this to my iPhone 13 Pro simulator. We'll give it a moment. Like I said xcode can be very slow. I'm going to preemptively pop open up this this log over here and it's going to let us see what happens behind the scenes. The build succeeded. That's awesome. Let this run real quick. I will watch this for the simulator. awesome simulators up and running it's going to toggle this feature real quick. Set the location to Apple Park. And we'll get our app up and running and hopefully we'll be able to see the location. As I give it a moment to just actually get everything up and running. And you'll be able to tell when everything is set as the device will be able to print some stuff out over here. This doesn't work. Yeah, see. Cool, so it does take a little bit to actually get all this stuff up and running subsequent runs will be faster. It's just because this was a cold start. I just approve that. Let's just stop real quick. And run that again. See already up in the running now you notice that we are trying to get. The current position but we have an error. This was intentional. The error is there the app has attempted to access some private privacy sensitive data without any usage description. So we need to add some native permission management here to allow us to get access to the data. so let's go ahead and copy this so NS location when in use usage description As I said, this is pulling in all of the actual, you know things that we need from both native and web. So we'll just come over here to an info.plist. You've never messed with info.plist before it is a fairly typical data format for At a row for setting things for your given project. We have our NS location when in use doesn't usage description. It's easier to say privacy. location when in use description We can set the value for this to be. I want to see. the location for the demo pretty pretty standard stuff location. There's a bunch of different values that we can do in here. So if you've opened up an app before Uber Uber Eats. Any kind of delivery app where you need where they need to know your location. There are different options here for like a one-time in use and always usage always in the background you can supply those privacy settings and hope that your users will be able to accept it and you can see see why they want their that location. You can tell them. I just want to see the location for a demo. So with that set let's rerun this again and open up our app. allow react Summit to use your location allow once and I'll go ahead and set the location to be Apple Park. You'll notice that we also get this little icon up here in the top corner for iOS. It's just going to indicate that something try to get our location now we can see the trail of events that have happened. So we blow to the app. web views loaded Geolocation request permission was our first call. So it automatically printed that out. We got the current position and decided to call native the location. Permission came back and we said granted everything is good. And then we have the results coming back from our get location. So our entire app is working as expected and we're getting the location back just well. so moving on from this we can start to try and customize the Android experience. So we'll go ahead and we will do the same thing set up opening up. Well first we need a sink Android because we didn't build and it does have its web assets. Work. Well, it's actually much faster than surprisingly. iOS We'll do MPX cap open Android. Now Android Studio if there's any fans of IntelliJ products webstorm phpstorm, this should feel pretty familiar to you. This is basically IntelliJ just Reef re-skinned or Android development So we'll give it a moment. It does take a little bit longer for it to start up at least for the IDE because it manages to fetch all the dependencies once you install so you can see we're importing all the different plugins and all the different tasks and letting it operate it also index all of our files so we can examine the entire project structure. Hey, everything looks like it's coming up good. All right, so we should now be able to go ahead and build this project so Much like we had to do for iOS. We need to provide the permissions here. and I I'll be honest. I don't remember it Android permissions. They are pretty different compared to iOS. Thankfully though. We have all of the plugins that are part of the core offering. The geolocation plugin will tell you what permissions you need to request. So let's go ahead and just copy these. And then inside of this app manifest Android manifest.xml. We need to print them or set them here. Notice we'll get this nice little tab over here saying where our permission should go. And we're just going to print these three permissions. You might get a little. Warning saying your permissions are outside the application tab. That's totally fine. The the app is going to still function just as well. With those permission set though. We can come up to the top of Android studio and we have our selection of devices whether it is a pixel 4 or pixel 3 or any real devices or we can create a new virtual device. I'll pick the pixel 4. We have the configuration for our app and then we'll hit this play button. At a spit up the entire emulator and you see I had a saved state from before when I was practicing with a different example. Let's let this kind of do its thing. As I said Android Studio can be a little bit slower, but it's not terrible. We can however disclose that I think. And if you're ever curious there is the full out. Put that happens when you are building your app. So you can check on that to see what's happening. Cool, so our app is up and running got deployed to the emulator just fine. Same thing as the iOS version the cold start for the app does and to take a little bit and this is only with the simulators though. So allow while using the app. Go ahead should try to get the location. It might have timed out because I took too long. Oh, let's just double click this to close it. Let's try one more time. React on it. Cool. We got our location. Again, the emulator is not the best development experience in my opinion. It can be very very slow it can. Not work great if you have an underpower device, or if you're trying to run for instance a zoom call and an emulator. and a bunch of other things all at the same time, so if you do have a device, so this is my Nexus. 5A. The last Nexus that LG made is my testing device. It's a lot faster than the emulator always worth testing on a real device too because you have access like notifications and everything. So right now we have our app running and it is using the longitude and latitude. We're getting everything up in coming back. It runs automatically in the web IOS and Android. Without me talking probably. 30-ish minutes and that's just waiting for things. All right. So we do have some questions over here. Is it possible finesse? Is it possible to store these permissions in a config or everyone who works with the same project should be set them manually for their builds. So very good question. These actually if we were just stop the run and then open up over here. So this is my that same project right? Um gives status. So we now have several files that are basically going to be part of Version Control. IOS and Android So once one person sets a permission. The full native project gets included into or once I've created a project. I should say that native platform gets added to Version Control. so Stephen if you if you made a change or added a permission and then you pushed it to get and then I pulled your changes down. I would get all of the permissions in here and be able to keep working in my project without having to constantly reset them. There could be some room for improvement in adding them in different locations and setting them via the typescript API, but at the moment they're still going to be available regardless of who's working on the project because they're all version controls. Hopefully that so just to recap what are the difference and benefits compared to react native again. Well automatically we now have basically a great way to start working. By not having to develop initially in the device. So if we were to run our deaf server again. So automatically be up and running we can start developing in the browser. First have the same access to apis in a much faster. development life cycle and eat from out of or keep Chrome in the focus It would sing. Come on react devtools. Cool. So all this is just going to start working versus react native having to set up a react native project having to configure all your dependencies. Basically learn the new tool and Syntax for it. This is basically just HTML JavaScript plus a few different JavaScript functions and it works in the browser right away. So I'm not having to learn a new development cycle. Now if you are someone who doesn't want to open up xcode or open up Android Studio, in fact, let's just close those down right now. Oh that that is just what I was going to disability what I don't like about react native like having accessible compiling taking time to do these things. And while you are developing usually will look for things that faster. So it's a bit sometimes annoying. So if there is alternative way to do this for example in web and then You have the same experience. That should be native to be brilliant. Yeah, I mean the same experience will be shared the same way. I was really nice is here. We're just developing in the browser and everything's working. But if we want to do we could do a little trick. So we could also just npm or MPX cap run. iOS Which will go ahead set up the entire build process for us copy all this over and instead of having to open up xcode. We now have a little picker over here where we could. Select our device. It'll go ahead try to run the build for us. and automatically deploy that to the iOS simulator so reducing the need to have to open up open up the X open up xcode it is really nice I'll let this run again real quick. Is there any other question? Oh, yes. We do. Have a question. Does a web view handle large projects where multiple native apis are made and doesn't handle animation like native does. Um, let's see. once whether you handle here, could you You explain what you mean a little bit more? You can come unmute if you would like. Yes, I was gonna ask if we make like calendar API maybe contact API lots of apis and the apis that for example, the react native uses the use needed drivers that boost the animation because I think the animations in capacitor made for CSS and HTML. those are the primarily animations I guess. Um, okay so well for the multiple native apis. Don't below all of the API access again, like said are in these official API plugins. So you mentioned the calendar and contacts leave. We do have a context plugin. If not in the official one. It is in the community plugins, which We have this huge community of third-party plugins that people have been maintaining for Bluetooth low energy background geolocation. Let's check the contacts. Yeah. Here we go. This is the contacts plugin that you can use and you can install this add the plugins and again here your permissions and then you can go ahead and get these added to your project. So multiple native apis can be used and Leverage. As for animations, you're probably going to do want to use a library for that since this is just web though. You could use something like framer motion. You could build your own animations using JavaScript and the web animations API a various different ways to to build all those things out. I wouldn't post I wouldn't say that that's necessary something that has to be handled through capacitor because that should be something that is part of your your web app design and design process Well, right, um cool. We did a one-time build and our app is up and running. I do want to show one thing that I really really enjoy and that is getting a faster development cycle. So we have this whole concept section over here and our docs and we have this live readload. If you're using this with ionic, we kind of cheat and provide a lot of the The work for you, but if you're using say react we could say posts. Equals npm Run start and I'll start your reacts Dev server. We can then set the blow and Safari we could then set the URL to point to the appropriate location inside of our capacitor project setting so we'll open up that real quick. And go to capacitor config. And then we'll have a server reference and get copied. Yeah. Don't need this anymore. Don't clear text. Also, just double check. Nope. I think it is. Yeah 30. Now I need to remember what my IP is. Yeah. Should be too big of a deal. And just double check that's working. Good. Awesome. Let's go ahead and then run. our MP MPX cap run iOS candle did same thing as before but instead of pointing it to our native assets or to our statically built stuff. It's going to point it to the dev server. Go ahead and get this up and running. Still be able to have our permissions maintained. But now when we come over to our project, if for some reason we wanted to not use a pre-tag or if we want to split this out do H1 patient up and running we could now start developing our app and have this whole entire thing. Just basically bound to our patient data. That's it you. basically now our development cycle is feels a lot more familiar to traditional web development. We're not having to go ahead and wait through these long compile times because we do have live reload in Dev servers. So all this is working really really well. And then it also works for app.css changes as well so we could get rid of this text align Center. I don't think we need it. A moment looking pretty good. Awesome. So this is basically you're now familiar deaths environment. Wanted to actually get this across because this is really really nice. If you are developing a very very large complex at it can be pain to have constantly go back and forth between Working in the browser to then deploy into the native device figure out that you need to change rebuild redeploy. This is working just fine on the simulator and is able to update in on real time as I make these changes. So if I get rid of the Slate one. It works the same way. This is not tied to just using a simulator. You can deploy to a real device as well and have that same experience working for you? Things that you can also handle here. If for some reason we wanted to come back to this react Summit app, and we want to change this name or even change the icons. There's various different ways we can do this. The dev server first. We have an extension here inside of vs code that's just called ionic. It's not tied to just the framework. You can see we have a whole bunch of capacitor configurations over here. And we can generate some custom Splash screens for you using some local tooling that gets included. So it'll use believe it's resharp to generate icons and splash machines for you and even include background and foreground colors for complex icons on Android. If you wanted to have some kind of a gooey way of opening things up in Android Studio in xcode you can do so or if for some reason you want to manage the build number in version number or completely rename the app to something like get Nation. It'll go through and rename the entire app for you. Then you could redeploy. And it would automatically update for you. Give that a second. And I don't need that don't need that. No issues found it'll go ahead ask me to pick my simulator again. And it'll automatically make sure that that is up to date. So I think if we sit here and watch Yeah, updated the name and still deployed to the device. So it's working really well here. Oh, um, I want to make sure check how we are in time. Oh. Don't believe we're gonna go through the full three hours that has been a lot of his Workshop, which is totally fine. It's it's a lot of information all at once. I do want to open this up for any more questions or anything else that people would like to know or our cares about So what's up front and console about running this on just web or on this Excel One? Android Studio so for like development while developing One more time. Sorry. What's the pros and cons? What's the point you have two options to running this locally? For example, just using your web. Like development kit or using Excel and Android Studio. So what's the process for running this on on a device that you're asking? Yeah, what is a advantages and disadvantages for this? Of the advantages. Okay, the advantage is that you get a quicker. Like on device feedback, like there are some things that can be emulated inside of the browser. with varying degrees of success, but if you're trying to Target mobile device, it's sometimes just better to deploy it to a real device. And know that that's what the experience is going to be for your users. So it's kind of how like it really depends on what you're trying to do and what you're trying to acute achieve I would probably I have a mapping app that I've been working on that. I always deploy to a real device just to make sure that the rendering of the of the web app in the web map are going to be as fast and efficient as possible. I could try to emulate that in the browser. But the device is just going to be the one that gives me the quickest and most real feedback. And if we are deployed to those devices, we'd be still be able to attach our Chrome Dev tools and inspect that and get that feedback on how the performance is going. yeah, I think that good answer but still while developing sometimes you need to just like not wasting the time moving between this platform. So you need to develop other income. I need to make test it fully in actual device and see if that were properly or not. But while developing yes, I can use like a Chrome browser and yeah, but if like, yes, sorry if there is a list of mapping to say what is available on browser and what is not available. So that's good to before you start build something for two days and then come after finds that's not supposed to so well for we can take a look in for instance actually geolocation. We do have support I believe it's some Used to be listed in here where you can see all the various different plugins and what platform to supported I think our docs team might have removed that so I need to open up an issue to get the added back. um Let's see. What is the average size or like what's the overall size for the app that this is generated? So just do a quick little build and we'll try to get A rough estimate of what this is going to be. I will say that the overall size. Will be significantly smaller. One ambassador's just try to run it on the simulator request to see if we can get a size of that. The overall size is going to definitely be a lot smaller than say a pure native app. Well, it'll be a little bit smaller than some of the cross platform Solutions and can be smaller than up here pure native app because the Tools independencies included are going to be a little bit better optimize. That breaks something in my app. Going out here. Let's just see. Oh I pointed the server to the wrong location. Anyways, let's if let's try so quick again one more time. We'll do the run again. So there is another question that to hear is. asking What big companies are using this technology? so do have actually aside for that. You have a slide. So we do have a lot of huge companies. This is constantly changing Burger King Blue Cross Blue Shield BBC IBM lot of a lot of large large Enterprises are using the stuff believe even I believe Target is also using it the capacitor docs would have a full full section on how what companies are using this stuff. Just try to see what we got here. I don't know why it's not working. Um. settings should be able to see the usage and everything. At least the app size. No, it's not gonna give me the size here in simulator average size probably somewhere in the with Native dependencies and deployed on the device somewhere anywhere between 80 megabytes to smaller a lot of the Areas where this could change is what dependencies are you including? What web assets? Are you including? Are you requesting stuff from a server or are you requesting things or including them locally? If you're including a bunch of videos or something that might include that month most likely is going to include the overall app size but most of the apps are pretty actually small. Blanking of where I can find the usage of this so I don't have an actual number that I can. Give you. Naveed what is the limitations of the capacitor against our versus a native app? It's a very good question. I would say that the actual. limitations are probably going to be 3D intensive graphics and that's not specific to capacitor. I think that's just a General comparison against the web native has really highly optimized apis for managing 3D Graphics creating 3D Graphics that the web just the web does not have that. So probably a better solution would be use something native in that get regards. But there's you could use unity in that case, which is highly optimized for cross-platform. 3D Graphics otherwise think of the apps that you use these days that are probably going to be just glorified lists and scrollers You can rebuild that in the web just fine. Um If you do want to learn more because I'm basically at the time with my with the workshop, but we have the capacitor JS website they can join. There is our dedicated docs that you can use here. And then this capacitor Community GitHub organization, which has a whole bunch of different plugins as I mentioned. We'll remove the query for this first. Don't know what that's still up there. How many plugins yeah, I mean we have things for date picker and intercom integration integrating Twitter kit. I had no idea that was a thing. Facebook login We basically have covered every single use case that you would want for developing an app and accessing third-party apis sqlite is a pretty fun one that people have often used. So if there's something in there that you want to try we probably have an API for it. so, um I believe I am at the time and everything for the presentation. If you again if you want to reach out you could tweet at me.
92 min
04 Jul, 2022

Watch more workshops on topic

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career