Auto Launch a React Native Mac App With Swift Dependencies
Get the project source code below, and follow along with the lesson material.
Download Project Source CodeTo set up the project on your local machine, please follow the directions provided in the README.md
file. If you run into any issues with running the project source code, then feel free to reach out to the author in the course's Discord channel.
This lesson preview is part of the Building React Native Apps for Mac course and can be unlocked immediately with a \newline Pro subscription or a single-time purchase. Already have access to this course? Log in here.
Get unlimited access to Building React Native Apps for Mac, plus 70+ \newline books, guides and courses with the \newline Pro subscription.
[00:00 - 00:25] Since we are developing a status bar application, you would expect to have an option for the up to auto start whenever you log in into your computer or whenever the computer starts. This is one of the main differences between a mobile device and a desktop device that you can have multiple apps running, right?
[00:26 - 00:36] So in order to do this, there is a manual process which is very complicated and is very time consuming. And there is one framework that can actually do this for you.
[00:37 - 00:48] It's called Launch at Logging. It's developed by Sindre, which is a developer that commits a lot of open source repositories.
[00:49 - 01:05] Now the problem with this framework is that it doesn't support GoCoapods. And the first time that I implemented this functionality, I didn't want to mess with even more package managers because they all have their quirks.
[01:06 - 01:16] But after doing this process myself, I have to admit, it's very time consuming. So if you can have something that does the heavy work for you, then that's better.
[01:17 - 01:27] So we're just going to go ahead and do this via the Swift dependencies. So here you can see the instructions on the give up repo.
[01:28 - 01:41] I'm just going to copy the address of the library. And on Xcode, I'm going to go into File, Swift Packages, Add Package Dependency .
[01:42 - 01:49] I'm going to select my main target. And I'm going to paste the URL in here.
[01:50 - 02:04] Now on some versions of Xcode, this is going to require for you to log in into GitHub. And if you have two factor authentication, that's also not going to work, right ?
[02:05 - 02:15] Because Xcode does not have access to your two factor key. So you might want to try to use the SSH address for this package.
[02:16 - 02:25] In my work, in my not, on this version of my version of macOS and Xcode, I don 't need to do it. I can just use the regular HTTP address.
[02:26 - 02:33] So give it a try. So I'm going to leave things as they are right now.
[02:34 - 02:41] And here at the next window, I'm going to change the target because I don't want to launch a login at iOS. That brings me nothing.
[02:42 - 02:57] What I want to do is add it to the macOS target. And then what the Xcode is going to do is going to fetch the package and it's going to add it to our project as a dependency.
[02:58 - 03:15] So now that we have the framework integrated, I need to do one more thing. If you go back into the GitHub repository, you will see that you need to add a script phase.
[03:16 - 03:20] So I'm going to go back into first. I'm going to take this value.
[03:21 - 03:25] I can just copy it. I'm going to go back into Xcode.
[03:26 - 03:39] I'm going to go into my macOS target and build phases. And after the copy bundle resources phase, this is where I need to insert my new file.
[03:40 - 03:53] So I'm going to click on this plus icon, run new script phase. I'm going to change the name to the launch at login script.
[03:54 - 04:06] And I'm just going to drag it to make sure that it's under the copy bundle resources. Here I am just going to take what I got from the repository.
[04:07 - 04:12] And I don't even need to save it. Everything is taken care of.
[04:13 - 04:30] So let's just try to compile the app and see what happens. So after compiling a wrap, you see that we got an error.
[04:31 - 04:37] Here I got a Swift get a big type conformance. It's not found.
[04:38 - 04:47] This really, if you're not a native developer, it's really hard to get a feeling for what might be wrong here. But it has to do something with Swift, right?
[04:48 - 05:00] I'm kind of showing you this in order for you to get a rough feeling of how you can get clues of what might be wrong, especially if you're not a native developer, right? You have to gather information from whatever you have.
[05:01 - 05:13] So this program is because we are embedding two versions of the Swift libraries . I found a solution by Googling, but we're just going to take care of it right now.
[05:14 - 05:18] So I'm going to go back into my explorer. I'm going to open the root object.
[05:19 - 05:32] And I'm going to make sure that I am on the project and select the value here from my application. Then on build settings, I'm going to search for the library search paths.
[05:33 - 05:45] And this is the key that I'm interested in. If I double click this, you should see in here that we here, like I said, we're integrating two types of the Swift libraries.
[05:46 - 05:55] So I'm just going to delete this key. And now I'm going to try to compile the app one more time.
[05:56 - 06:00] And there you go. So our application has compiled.
[06:01 - 06:08] Now we have the framework fully integrated into our library. Now it's time to connect it to our UI.
[06:09 - 06:28] So once again, I'm going to use a very known trick by now, which is I'm going to expose native functionality to our JavaScript side of things. And I'm going to call this get start at login status, right?
[06:29 - 06:41] This is going to be a function that is going to extract the current value of the flag that we're going to set in order to start the app. So we can display it on the UI.
[06:42 - 07:07] This one is going to take the RCT promise resolve block, which I'm going to call the resolve function. And the rejector is going to be the RCT promise reject block, which is just a reject.
[07:08 - 07:12] Great. So this is going to allow us to read the value.
[07:13 - 07:23] We still need to add one more to set the value. So set start at login status.
[07:24 - 07:40] And this is going to take Boolean, which is the status. I'm going to go back to my Swift object.
[07:41 - 07:49] This time I'm just going to take the code from the lesson. And there you go.
[07:50 - 08:03] There is one more thing that I need to do, which is I need to import the library. Launch add login.
[08:04 - 08:06] Great. So now, let's go.
[08:07 - 08:17] It's not throwing any errors. Let me compile the app.
[08:18 - 08:25] Great. So the application starts.
[08:26 - 08:41] And now I just have to show it to the user. Once again, on my native class, I'm going to get start at login status.
[08:42 - 08:53] This one returns a promise with a Boolean inside of it. And the set start at login status.
[08:54 - 08:59] This takes the status as a Boolean. And this is just void.
[09:00 - 09:13] I mean, of course, I could return a promise, but I'm just going to assume that 's going to work at the first try. Set start at login status.
[09:14 - 09:21] And get start at login status. Great.
[09:22 - 09:38] So now I only need to display a UI element for the user to see what is being done. Let me just check it if everything is all right.
[09:39 - 09:51] Great. So on my books container, I am going to add another promise.
[09:52 - 10:02] So I'm going to add a flag, which is going to be my start at login status. And set start at login status.
[10:03 - 10:09] I'm going to use a use state that's going to start as false, right? The application starts.
[10:10 - 10:27] We still don't know if the flag has been set or not. On my use effect hook, I'm going to add going to call my building apps native, get start at login status.
[10:28 - 10:48] That promise is going to resolve and whatever that results to, I'm going to pass it to my set function from my hook. And then down here, I am going to add a text.
[10:49 - 11:04] Let me add first a view inside of it with text. And here I'm going to say this is launch application at login.
[11:05 - 11:17] I'm going to use a switch component, which is part of React Native. The value is going to be my start at login status.
[11:18 - 11:30] And whenever the value changes, I need to call my native function. So I'm going to call the building apps native.
[11:31 - 11:53] Let's start at login status with the negated value of start at login status. I also have to replicate the status at my local flag.
[11:54 - 11:56] And there you go. So now.
[11:57 - 12:04] This is probably because we now have more hooks. Let me just check one more time.
[12:05 - 12:16] Yeah, it doesn't matter. So I'm going to dismiss these errors and then right click and reload the application.
[12:17 - 12:23] Great. And here you can see now we have our launch application at login.
[12:24 - 12:38] If I set this and let me just reload the app to make sure everything is working , then it will be working. Now I cannot show you this in action because then I would have to login and my screen would stop recording.
[12:39 - 13:01] But when you're developing this on your own, you can package your application, archive it in release mode because you need the app to be somewhere stored independently. Like you cannot run it from Xcode, turn on the flag and then when you turn on your computer expected to run, the application needs to be packaged.
[13:02 - 13:14] So just a quick tip. If you don't know how to package the application, you go into product archive and then it's going to produce some options where you can export the application.
[13:15 - 13:27] Then you run it and if you set this value to true and you restart your computer or you can log out and log in one more time. Then your application should be there when the computer starts.