React Native Radio

RNR 177: Challenges of Building RN Apps in iOS vs Android

Episode Summary

In today's episode, we explore the challenges of building cross-platform apps in React Native and look at the differences between the two main platforms, iOS and Android.

Episode Notes

This episode brought to you by Infinite Red! Infinite Red is a premier React Native design and development agency located in the USA. With five years of React Native experience and deep roots in the React Native community (hosts of Chain React and the React Native Newsletter), Infinite Red is the best choice for your next React Native app.

Show Notes:

Helpful Links:

  1. Adhithi's article about the differences in building iOS and Android apps in React Native.
  2. This week's weird bug
  3. Learn more about Elevation, here!
  4. Interested in learning more about Google Play Console pre-launch reports? Take a look at this!
  5. Google Developers India — Android app walkthrough
  6. Orta gave a wonderful talk about iOS build infrastructure, You can watch that here
  7. Have some busted node modules that need fixing? Check out Patch Package!
  8. Here's how the devs at Infinite Red setup Fastlane and Circle CI

Connect With The Hosts!

Episode Transcription

Todd Werth:

Welcome back to React Native Radio Podcast. My name is Todd and I edit this podcast. Episode 177, differences in React Native Android versus iOS.

 

Jamon Holmgren:

Everyone, welcome to React Native Radio Podcast where we explore React Native together. I'm your host Jamon Holmgren, and I'm joined by my three fantastic co-hosts. How are you doing Harris? 

 

Harris Robin Kalash:

I'm good. How are you? 

 

Jamon Holmgren:

Doing well. Doing well, of course. Adhithi, how are you?

 

Adhithi Ravichandran:

I'm doing well. How are you?

 

Jamon Holmgren:

I'm doing great. And Robin. Robin, how are you?

 

Robin Heinze:

I'm great, Jamon.

 

Jamon Holmgren:

But you didn't ask me how I'm doing.

 

Robin Heinze:

Oh, how are you doing today?

 

Jamon Holmgren:

I'm doing terrible, thanks for asking. Today, this episode is sponsored by my company, Infinite Red. Infinite Red is a React and React Native consultancy. So if you want to talk with us to potentially work with you on your React to React Native project, send us an email, hello@infinite.red. Today's topic is a fun one. Well, fun for nerds anyway, the topic is differences and challenges in Android versus iOS when building a React Native app. 

 

Jamon Holmgren:

So obviously React Native supports more than one platform, specifically out of the box, it supports iOS and Android. But there are some differences between the two. And I remember when React Native first came out, its slogan was learn once, write anywhere rather than write once, run anywhere. However, over time, it's kind of become more of the latter, it's kind of been more, you can write once, and then run it anywhere. But there are differences. And so that's the topic today, we're going to talk about our experience working on React Native apps and what the differences have been between those two platforms. 

 

Jamon Holmgren:

There are other platforms, of course, there's Windows, and there's MacOS, tvOS and other platforms, the differences there will be more pronounced. But in the case of iOS and Android, we're talking about something with a very common purpose, both being the most popular mobile OS’. Kind of funny little story, I was doing show prep this morning, and read through a great article on Programming with Mosh from July, it was called Differences in Building iOS and Android Apps Using React Native. So very, very relevant. I was taking a bunch of notes and I was just kind of like, "Man, this is a great article. It's got all kinds of cool stuff." And then at the bottom, I realized who the author was, and it was Adhithi.

 

Adhithi Ravichandran:

I do write for Programming with Mosh, that's right. I actually write React Native and GraphQL-related articles for him. 

 

Robin Heinze:

So yeah, this is Adhithi's topic.

 

Jamon Holmgren:

That's awesome.

 

Adhithi Ravichandran:

I actually did go through some of my blog posts and then just pick one of these topics from there. So it's like, "Okay, this sounds cool." A lot of the times I just write these posts and then forget about it and few months later, I run into them again, and I'm like, "Okay, cool. I wrote this, I guess. It answered some of my questions," because I just forget, again.

 

Jamon Holmgren:

You're a prolific writer and it's awesome. I've done that myself, run into my own Stack Overflow answers and things like that. It's really fun. But yeah, that was kind of funny. I was just thinking, "This is a great article," one of the best I found when I was doing show prep, it was you.

 

Adhithi Ravichandran:

It's probably the same title, so it's easier for you to find it.

 

Jamon Holmgren:

Now you know what I Google, yeah, I just Google the topic.

 

Robin Heinze:

Let's also not breeze past the fact that Jamon just admitted that he preps for the show the morning of.

 

Jamon Holmgren:

For those who know me, that will be no surprise. I did do some prep yesterday, last night. I did do some prep last night as well. But I left the tabs open, and then this morning, I was finishing up I guess, a half-hour before the show. 

 

Robin Heinze:

Freshen up your brain. 

 

Jamon Holmgren:

I will say that I'm the least experienced with this. Well, I guess there are parts of it that I've done more of, especially with the native component side of it. But the three other panelists here are going to have a lot more hands-on experience. So I'm going to be leaning on you all to provide the amazing content-

 

Robin Heinze:

Happy to carry the load.

 

Jamon Holmgren:

So let's start with sort of, I think, what was probably one of the bigger parts of this and that is developer experience. What types of things would be different between when you're looking at the Android side of things versus the iOS side of things and don't be afraid to even talk about obvious things, let's start with Harris, do you have-

 

Harris Robin Kalash:

Sure.

 

Jamon Holmgren:

... something in mind?

 

Harris Robin Kalash:

Yeah, one of the biggest pain points when I was implementing designs in React Native is Android never seems to... well, Android doesn't support shadows yet. So then taking that design and having to use Android elevation doesn't always work out very well.

 

Jamon Holmgren:

Explain the elevation thing. I did learn about that this morning. Thank you, Robin. I did learn about that. I don't generally do UI programming in the stuff that I do, so what's this elevation property? 

 

Harris Robin Kalash:

Yeah, elevation, I actually never really read the documentation on it, so please correct me if I'm wrong anywhere, but I believe it's this opinionated material UI shadow, that allows you to have... I mean, it gives you a shadow, but it's opinionated. So it's not necessarily the shadow in the design, it's really material UI's shadow and it has a number, I believe, between one to maybe seven or something. And the higher the number, the, I guess, more elevated the shadow, the bigger the shadow and the radius and all that stuff.

 

Robin Heinze:

Yeah, it mimics as if you were literally lifted the element above the page. And the shadow sort of mimics that and it gets more diffuse the higher you go and further away, and it gets closer in if it's closer to the page, the shadow gets tighter. But you can't explicitly control those values like you could with a drop shadow.

 

Jamon Holmgren:

Do you find that the designers get irritated? It's like, "Hey, you were supposed to do this type of shadow and you didn't do it."

 

Robin Heinze:

Absolutely. They don't get irritated at us, but I've had to go back to our designers and explain that we couldn't implement the shadow the way it was designed on Android and they're more annoyed at the technology limitations, not at us.

 

Jamon Holmgren:

Yeah, totally. It doesn't just affect the shadow, it also affects the Z order of overlapping element. So it sounds like it's kind of a all-in-one property. Seems a little clunky to me.

 

Harris Robin Kalash:

What I don't like about is it gives you this two-source-of-truth type of thing, where if I want to modify my shadow, now I have to worry about modifying the actual block shadow and the elevation on both platforms. That sucks.

 

Jamon Holmgren:

Is there any way to kind of abstract that so that you can at least be like, "Okay, I'm going to use the same property for both." I suppose you could just build a custom component that-

 

Robin Heinze:

Yeah, on several of my projects, I've had to build a custom shadow component, which just wraps its children and applies the shadow that I want for that project.

 

Jamon Holmgren:

That makes sense to me, totally makes sense. And it sounds like that's elevations Android only, of course, and it goes from Android 5, and of course, that's a pretty old one. So Robin, do you have another example of something that gets in your way when you're doing development? Your development experience when it comes to iOS versus Android?

 

Robin Heinze:

Yeah, I think a really common one that makes a huge impact is device testing and emulator and simulator testing. With iOS, of course, you have all the simulators that come out of the box with Xcode and they perfectly mimic the iOS devices that are in the real world. 

 

Jamon Holmgren:

Not perfectly, but pretty close.

 

Robin Heinze:

Not perfectly, but pretty close. And it's from Apple, so you can depend on them to be pretty accurate. Whereas with Android, you have out of the box emulators from Android Studio, which are all Google devices. And you don't get an emulator experience for things like Samsung devices, which is actually quite problematic because Samsung has a custom flavor of Android, and so it doesn't always behave the same.

 

Jamon Holmgren:

It's also the most popular Android brand.

 

Robin Heinze:

Yeah. It is. So you can't really get away with not having physical devices. I have a whole drawer full of Samsung phones and tablets because that's really the only way to test the Samsung Android.

 

Adhithi Ravichandran:

This keeps happening to us as well in our company. All of our testers have Samsung phones and they're like, "Hey, it doesn't work on my S7." And I'm like, "S7, what's the dimension?" So most of the time, it's related to the height and width of the screen. So then I have to compare what the height and width of their devices and then try to have an emulator pretty close to that. But there are specific problems you'll see in Android related to the Samsung issue because you just don't have emulators for it. And you need a physical device to debug on. So that's definitely a big problem. 

 

Robin Heinze:

There are Samsung device farms, remote device farms, I think they call it the device lab or something, where you basically remote into a Samsung device. But the times that I've tried to use it, it's so slow that it's virtually unusable. 

 

Adhithi Ravichandran:

Yeah, I think it's like, "Is that a VM or something they have there?" 

 

Robin Heinze:

I think it must be. 

 

Adhithi Ravichandran:

Yeah, it is slow. I've tried that too, and I feel like just directly testing on a physical device is probably faster. 

 

Robin Heinze:

There's some pretty inexpensive ones on Amazon if you go for refurbished, slightly older versions, you can get some good deals.

 

Jamon Holmgren:

And the benefit of that is you're getting a slower phone so that your experience would mimic someone on a slower older device and if there's a problem, you're going to encounter it.

 

Harris Robin Kalash:

There's also a really, really underrated feature in the Google Play console, it's called pre-launch reports, I don't know if anyone has actually ever tried them.

 

Adhithi Ravichandran:

I haven't. 

 

Robin Heinze:

Yeah.

 

Harris Robin Kalash:

Have you tried them, Robin?

 

Robin Heinze:

Yeah, I look at them pretty much every time I release an Android app, there's usually a lot of errors that I ignore, warnings that you can't do anything- 

 

Adhithi Ravichandran:

What is this report?

 

Harris Robin Kalash:

So it's extremely underrated. When I first discovered it, I was blown away. Essentially, what happens is that Google will actually run your app on multiple devices, multiple operating systems. And it's really smart about clicking everywhere, so it'll literally almost brute force your app.

 

Adhithi Ravichandran:

Nice.

 

Harris Robin Kalash:

Yeah. It's really smart also about pulling out issues. So if a button is not clickable, you'll see it in the pre-launch report, it'll tell you like, "Hey, there's an issue here. I'm clicking here, it's not taking me anywhere. I click here and it crashes." And it gives you this giant report that Robin mentioned, even me when I open it, there's so many errors in there that Google catches that I don't, so.

 

Adhithi Ravichandran:

That's good to know. I haven't tried that at all, I'll definitely check it out. 

 

Harris Robin Kalash:

I highly recommend it.

 

Robin Heinze:

If your app is behind a login screen, though, that's one thing it can't do. Yeah. So I mean, during the iOS app approval, it's an actual person, so they can enter in a username and password that you give them but the Android pre-launch reports are all automated. 

 

Adhithi Ravichandran:

I see. 

 

Robin Heinze:

So that's one downside. 

 

Harris Robin Kalash:

Yeah. But it also measures performance, start time memory usage, all for free. I highly, highly recommend. 

 

Robin Heinze:

Yeah, they're very comprehensive.

 

Harris Robin Kalash:

Yeah. It's all free, by the way.

 

Jamon Holmgren:

That sort of shows the difference between the approaches of Apple and Google. Apple's like, "Hey, we're going to have a person sitting here, they're going to be trained to look for things and they're going to manually go through your app and see how it feels from a human stance." Google's-

 

Robin Heinze:

It's a very subjective process.

 

Jamon Holmgren:

And then Google's like, "We're going to write a script."

 

Robin Heinze:

Yeah, exactly. Much more quantitative. And one thing is, I don't think they actually reject your app based on those reports, I think it's all informational.

 

Jamon Holmgren:

Adhithi, do you have an example of where the developer experience can be quite different when you're deploying or building for iOS versus Android?

 

Adhithi Ravichandran:

Yeah, the most common thing that we'll run into is basically the tool set. If you look at iOS, you'd be using your MacBook and you'd be using Xcode, all of that stuff versus for Android, you could even use the Windows laptop if you wanted to and you have Android Studio and the JDK and all that. So I think the tool set being different and you have to deal with like Gradle settings for Android and deal with all the Xcode stuff. So that could be a bit overwhelming when you start off because you have completely different sets of IDEs and everything. 

 

Adhithi Ravichandran:

Because once you're developing your app, if you go back into these tools, you'll be like, "Oh, I have to build my app for Android using something called Gradle. Now, what is Gradle? How do I resolve all these Gradle build errors?" That's always been a challenge for us even with onboarding newer engineers, there's just so much differences between iOS versus Android toolset. Although we share the code when it comes to custom code, when it comes to deployment, you still have to deal with all these tools unless using Expo. So that's definitely a difference or a challenge. 

 

Robin Heinze:

I would say I still spend a lot of time Googling Gradle issues. 

 

Adhithi Ravichandran:

Yeah.

 

Jamon Holmgren:

Yeah, totally.

 

Robin Heinze:

Yeah, that's a lot of knowledge to have.

 

Adhithi Ravichandran:

And you have to keep up with all the new Android releases as well, and you have to match those. It is tough, yeah. It's definitely challenging. The Android side of it is more challenging, in my opinion, than iOS.

 

Harris Robin Kalash:

Yeah, I mean, I completely agree with you. I feel like Android is definitely the biggest pain point. But I also find the performance offender devices extremely inconsistent compared to iOS devices. 

 

Robin Heinze:

Yes.

 

Adhithi Ravichandran:

Yes. And I think if you have more screens, as the stack keeps increasing, the performance is going down exponentially, I've noticed that. And definitely the Hermes engine helps with that, but before that you could definitely see a lot of lag in animations and stuff.

 

Robin Heinze:

Definitely. Especially in dev mode, Android is especially slow. 

 

Adhithi Ravichandran:

Oh, yeah. 

 

Robin Heinze:

Which peaks the developer experience. 

 

Harris Robin Kalash:

I could feel the pain. 

 

Robin Heinze:

Yeah, you'll feel the pain to an exaggerated degree.

 

Jamon Holmgren:

Yeah. And you can't really rely on the simulator or the emulator to give you that feel, you really have to be on a real device in both cases really, to see what those different performance profiles feel like. Going back to Gradle for a second, can you explain sort of what Gradle is for people who maybe haven't used it, Adhithi?

 

Adhithi Ravichandran:

Let me Google it.

 

Robin Heinze:

It's kind of like CocoaPods.

 

Jamon Holmgren:

So let me restate the question. I'll actually answer it if that's cool. 

 

Adhithi Ravichandran:

Okay. Yeah, sure. 

 

Jamon Holmgren:

For those who don't know, Gradle, it's a package manager, sort of like NPM. But it's also a script runner, so you can run scripts for setup. We generally don't have to do too much in the way of custom stuff or usually, it's like you're following this blog post and it says, go to this Gradle file, gradle.settings, or something.gradle, app.gradle or something, and then build.gradle. I don't know, there's so many Gradle files. And then you go to that file and you insert a line somewhere and then everything magically starts working. That's kind of the experience of a React Native developer. I would recommend that people go and do an actual... if you're interested in not always feeling kind of out of your depth, that you go and do... 

 

Jamon Holmgren:

So I think Google Developers, India, or something like that, I think it was Google Developer, India, put out a really good intro to Android Development series on YouTube. And I went through part of that, I haven't gone through all of it. And I learned so much about Gradle, and why certain files exist and where they exist. I'll put a link to that in the show notes. But it's not difficult to go through, you probably don't even necessarily need to code along with it, you can just watch it if you want. Although coding along I think does help. But you're just sort of setting up an initial Android app and not React Native. 

 

Jamon Holmgren:

And then once you get into React Native, then you'll know, "Okay, that's why I'm going to this Gradle file and making this change, and that's what this means," et cetera. They also point out certain things like when Android Studio is loading, don't click too quickly over here or else it'll crash. They literally will point stuff like that out, which is helpful just for, "Okay, I know at this point, I need to let it load." So I'll put a link to that. I do recommend people do that. You'll feel a lot more comfortable within the build system and Android once you get a chance to do that. 

 

Jamon Holmgren:

And I think I've mentioned this before, but there's a great talk at React Native EU on Xcode, and we'll put a link to that as well. That was from ORDA. So I think if you went through both of those things, then you have a much better just level of comfort with these build systems.

 

Robin Heinze:

That Android Studio is the reason I had to give a bunch of money to Apple to buy a new upgraded laptop.

 

Adhithi Ravichandran:

It makes all kinds of noises, right? When you open up Android Studio and then your laptop's just running really hard too. 

 

Harris Robin Kalash:

Speaking of not clicking somewhere in Android Studio when it just loads so it doesn't crash, one thing I still don't understand, what is Android Studio doing all the time. When I open Xcode, it's like it calms down at some point, whereas Android Studio is always doing something, I just don't understand what's, my poor laptop.

 

Robin Heinze:

I think it's syncing, doing something to sync Gradle constantly. 

 

Harris Robin Kalash:

Yeah.

 

Robin Heinze:

I am not positive though.

 

Adhithi Ravichandran:

I tried building React Native apps for the first time using Windows machine. At that time, we just needed an android version real quick. And my goodness, it was I think... yeah, it was a horrible experience because my machine just gave up. It couldn't do it anymore. And that's when we switched to MacBook and we're like, "Okay, doesn't make all those fan noises as much."

 

Jamon Holmgren:

Yeah, it'd be nice to get a Google engineer on the podcast to talk about that and why that is, why it's architected the way it is. I do know that obviously, Xcode can be written specifically for OneOS. And for One, it's deploying to one type of architecture more or less. Although that will change a little bit now that they're going to arm but Android Studio is built on the JVM, it's like this fully virtual machine situation where you can run it on any system. So there's just so much more code that has to be loaded and so many more updates. I agree though, the developer experience isn't the greatest sometimes in that situation.

 

Robin Heinze:

So should we talk about UI differences? 

 

Jamon Holmgren:

That'd be great. 

 

Robin Heinze:

So I think some of the big ones are with the native components, like you're talking about alerts, and text inputs, things like that. 

 

Adhithi Ravichandran:

Day pickers.

 

Jamon Holmgren:

These are provided by the native or the underlying operating system. So you call in and you say, "Hey, I need an alert, and it gives you an alert, but it's going to style it the way that it thinks it should be styled," is this generally an issue? Do you think? Or do you think that users expect alerts to be in those styles?

 

Adhithi Ravichandran:

I haven't seen much of an issue, those with the Android devices, and if they compare, we do applications for the healthcare setting. I've noticed when the clinicians compare between devices, if Person A has iOS was on Android, they're like, "Why does this look so different?" Because they're used to their muscle memory, and then if they switch devices and the calendar looks completely different on a Google device versus an iOS, they're like, "What's going on?" 

 

Adhithi Ravichandran:

Because I think, on Android, we literally show physical clock and you can pick your date time versus in iOS, it looks totally different. But I think it's a matter of education, the IT or the support, we just need to like explain to them this is a device specific difference. It would be really a bad way of spending our time to mimic how it looks on iOS and Android, because then it defeats the purpose of rendering native components. So I think from our perspective, we try to educate our users that it is going to look different because it's native components, yeah.

 

Robin Heinze:

I've had designers basically give us a design where there's a custom alert for both platforms. And often I will actually push back a little and say, "Hey, can we stick with the native alert designs, because A, it saves us time and money and B, it sort of keeps the experience consistent for the users who are used to seeing a specific alert with a specific number of buttons and location of buttons. It can actually be quite jarring if you're used to the cancel button being on the right and now it's on the left or something like that. And so I generally tend to recommend just sticking with the pure native components for situations like that.

 

Jamon Holmgren:

When I first started doing mobile application development, we used to design apps for iOS and Android separately. So you would specifically do an iOS design and you would specifically do an Android design. And often they actually felt like your kind of default app in an Apple app. And that was done because it was more trustworthy at that time. It was like it feels like your just basic Cocoa Touch UI, people are going to trust it more. Now, today, that's laughable, nobody would do that. That seems like someone doing a tutorial and then they're done, but at that time, it was actually pretty common. 

 

Jamon Holmgren:

So now having the same custom style is common for the majority of the app. But you don't want it to feel like... if you're on an Android app, or you're on an Android phone and you download an app, and it feels like an iOS app, you're going to feel like, "Ah, this isn't what I want." And same vice versa. So to get around that rather than doing kind of custom, iOS specific and Android specific, you just go full custom and you make something that's really just about you and your brand. But you still want your standard paradigms, for example, the platforms steal ideas from each other all the time. Things like tab navigation, pull to refresh, these are just-

 

Robin Heinze:

Drawers.

 

Jamon Holmgren:

Drawers, exactly. These are common paradigms. So at this point, you can pretty much have a design that users of both platforms will accept as being native to their platform, but you can implement it once. 

 

Robin Heinze:

I don't know if it still is. But I mean, up until recently, it was actually kind of controversial to use the same design for both iOS and Android. I think there's probably still a lot of purists who think that each platform should adhere to the conventions of iOS versus Android. I mean, things like Android apps tend to have action buttons that are sort of floating in the bottom corner like a new message button in Gmail or whatever. And iOS tends to put those in the header, those kinds of little conventions, if you have the same design for both platforms, you're obviously not going to be doing those.

 

Jamon Holmgren:

So that is possible, right? With React Native, you can do that. And that's through the file extension, is that right?

 

Adhithi Ravichandran:

Yeah, you could do that. React Native is smart enough to detect the device and render the component accordingly. So you could have an extension that says mycomponent.ios.js for your iOS styling, and for Android, you could just have the .android.js. Yeah, we use this, but not too often, but it helps out with having the style separated out iOS and Android specific style. So that's definitely helpful.

 

Jamon Holmgren:

How often do you use that?

 

Adhithi Ravichandran:

I would say, quite rarely, we don't use it too often.

 

Robin Heinze:

Yeah, I don't think I've ever used it, three and a half years, I don't think we've ever done it.

 

Adhithi Ravichandran:

I think we have a few files like those just to please some clients for specific styling they needed, but I don't necessarily think it's required, but it helps to have something like that just to keep them separate. But from a developer perspective, we try to stay away from too much customization, just because we really want to achieve the shared code between the devices.

 

Robin Heinze:

Well when you're working for clients, pretty much all you have to do is say, "It's going to cost you less if I build this once instead of twice." And they'll go for it. 

 

Harris Robin Kalash:

Those are the magic words.

 

Adhithi Ravichandran:

So your clients are different. Our clients, we're trying to please them after building the product and selling it to them and asking them to buy a product versus your client is asking you to build a product for you, right? You're a consulting company. So there's a small difference here, we're like, "Oh, please take our product, buy this." It's great. It's going to do everything you want. So. 

 

Jamon Holmgren:

Makes sense.

 

Adhithi Ravichandran:

We're in a different route here.

 

Robin Heinze:

Yeah, that is a completely reversed perspective. 

 

Adhithi Ravichandran:

Right. Yes.

 

Jamon Holmgren:

You can also do, and this is going outside of the iOS and Android space, but you can do .native.js, and then you can do .web.js to target web versus native. And this will be a future episode, but the project that Robin's working on right now is actually a web and native iOS and Android app, and they're sharing a ton of code between the two. But we're doing something kind of different and it'll be really interesting to bring that up in a future episode and talk more about it. How's that for a teaser?

 

Robin Heinze:

Teaser.

 

Harris Robin Kalash:

One use case of the .Android and iOS extension is because on iOS, you have this picker where you can scroll through it, on Android that's not the pattern, right? It's like a modal drop down. There are two different components with different props, so what I do is I combine them into the same one and then I have the extension. I'm surprised- 

 

Jamon Holmgren:

So you write a custom component that then kind of abstracts that and can build either?

 

Harris Robin Kalash:

Yeah, exactly. We've done that actually on a few projects at Infinite Red.

 

Robin Heinze:

That's one of the beauties of React, right?

 

Jamon Holmgren:

Yeah, totally.

 

Adhithi Ravichandran:

One other thing I thought about was the physical back button that Android has and you don't know that when you do the iOS devices, and then you're like, "Okay, what do I do now? Where should this go?" 

 

Robin Heinze:

Yeah, it's an afterthought in a lot of projects. 

 

Adhithi Ravichandran:

Exactly.

 

Jamon Holmgren:

I use an iPhone X for my daily driver, but I have a Pixel 2, I think, and it does not have a physical back button. And I've actually set it to the setting, which makes it feel more like iOS where it doesn't even have a software back button anymore, you just swipe from the left corner or the left edge. So when I'm using it, it does feel a lot more like an iOS device, but if I were to be testing something, I probably shouldn't do that, I probably should have the physical back button, I should probably use it like an Android developer, or an Android user might rather.

 

Robin Heinze:

And if you're not an Android user yourself, it can be really easy to miss some of the patterns that Android users expect, forms that have a cancel button. Android users are expecting to be able to hit the physical back button and have it perform cancel behaviors, things like that.

 

Jamon Holmgren:

Context aware.

 

Robin Heinze:

Yeah.

 

Harris Robin Kalash:

Yeah. I mean, you can also exit the app with the back button, right?

 

Robin Heinze:

Mm-hmm. If you don't handle it explicitly, it'll crash your app. So watch out for that.

 

Jamon Holmgren:

What about when, for a developer experience side of things, writing native integrations. So if you are actually writing some native code under the hood or you're integrating some sort of native SDK, those would be different processes between iOS and Android.

 

Robin Heinze:

Obviously, the language is going to be different. You have Java versus Objective C or Swift.

 

Jamon Holmgren:

And there's quite a difference between Java and Objective C. I mean, they're maybe some surface similarities, but they are quite different languages, Swift and Kotlin are a lot closer, because I think they had similar influences on them. They were kind of developed separately, but at the same time, and they tended to kind of follow patterns that most modern languages tend to follow now. But even then there are differences between Kotlin and Swift, although if you were to look at a bit of code, you'd have to be a fairly practiced developer to even notice right away which one is which, they have a lot of similarities. But there are a few things that are different between writing the two. So when you write a native integration, do you find that you tend to have to kind of completely shift gears when you switch from iOS to Android? Or can you kind of copy it line by line, but you're mostly just translating between the two languages?

 

Robin Heinze:

I mean, personally, I've never written a native integration. I think the library we have of different components and SDK integrations is pretty robust. We have a lot to choose from a lot of things that people have already written. So I've actually never had to write my own custom. That is probably not the case if you're building a bigger app for a larger company.

 

Adhithi Ravichandran:

That's the same with me. For some reason, I've really never needed to write any custom native code.

 

Harris Robin Kalash:

Whil, I've never written one, I had to dive into native code a few times to fix certain packages. And I just want to say patch package is extremely useful in React Native.

 

Robin Heinze:

Yeah. 

 

Jamon Holmgren:

Yes. 

 

Robin Heinze:

It is a lifesaver. 

 

Jamon Holmgren:

Explain that, Harris.

 

Harris Robin Kalash:

Yeah, absolutely. So shout out to patch package. It's a node package that essentially does a diff between an original package. So what you do is create a patch folder, you can create a patch for a particular library, and what it'll do is it'll create a specific patch file for that version of the library. And it'll do it a diff between your changes in that file and the original package. So you actually go into the node module or into the iOS file, or whatever, and make your changes right there. And you would run patch package, and you would constantly overwrite that package with your changes. It's really useful if you're waiting for a fix, and that's not on master yet. So you could just write your own patch. What I do is I run it in a post install, so it'll just overwrite that every time you do-

 

Robin Heinze:

It's a much, much more elegant workflow than forking packages. 

 

Jamon Holmgren:

Oh, yeah, totally.

 

Adhithi Ravichandran:

We use it all the time too, Harris. It's definitely awesome to use that instead of forking.

 

Jamon Holmgren:

Yeah. When I first heard of patch package, I was thinking, "Man, that just sounds super hacky and I feel like there would be problems." And would you remember what you were patching and things like that. But just the way that it's set up is super, super developer friendly, it will warn you if the package that you are patching has been updated, and you can kind of make sure that it is still compatible or maybe the bug was fixed, then you can remove that patch. It's just really good work. David Sheldrick from Artsy is the one who built it, and like everything from Artsy, it's just fantastic open source.

 

Robin Heinze:

Hey, I do wonder, I would be curious if patch package either encourages or discourages people from actually making PRs against the packages that they use? If they find-

 

Jamon Holmgren:

It's a good question. 

 

Robin Heinze:

I don't know. I mean, if it encourages them to find the bug themselves and find the fix, then maybe it would help, but if you have a way to just patch it in your own project, maybe you'd be less likely to make PR, I don't know.

 

Jamon Holmgren:

That's probably true. I have seen people post patches in issue threads which would then help someone create a pull request from it. So that's a pretty low friction way to do it. You don't have to fork it, you can just throw the patch in the issue thread and someone else might feel like, "Oh, yeah, I can make a PR for that." But you're right, Robin, that's possibly could. It fixes their problem, so then they move on.

 

Harris Robin Kalash:

Especially if you're dealing with native code and you're not well versed in that, seeing a patch in an issue has saved me quite a few times.

 

Jamon Holmgren:

So, what about platform.select that is a function that comes off the platform module in React Native and it can be used for many different things, but where I've commonly seen it used is in styles. So maybe there's a style, for example, the drop shadow situation, being able to select between the different platforms is helpful. So you don't have to fork the whole file and name it .android.js or .ios.js, instead, you can just do it right in line in the code.

 

Robin Heinze:

I use it all the time, especially since like you said, we're working on a mobile and web project right now, we use it all the time. It's very, very useful.

 

Adhithi Ravichandran:

I agree. We use it very frequently too. We don't use the same styles for our web, but we definitely distinguish between iOS and Android and that definitely helps you.

 

Robin Heinze:

I did just learn recently about the native and default options using platform select. It's not just iOS and Android and web, if you have a style, like in our case, if we have a style that only applies to mobile, it's making something fit on a small screen, something like that-

 

Adhithi Ravichandran:

Interesting-

 

Robin Heinze:

... only applies to mobile, we can use native and then web for the web style.

 

Jamon Holmgren:

What is default then in that context?

 

Robin Heinze:

A default would essentially be the same, it would function the same way-

 

Jamon Holmgren:

Anything else.

 

Robin Heinze:

Right, it's anything else, but we don't have any other platforms besides native, so they’re basically equivalent.

 

Jamon Holmgren:

I see. Oh, that's cool. That's very cool.

 

Adhithi Ravichandran:

One other thing I've noticed is between iOS and Android, some components, they have styles and props that act differently on iOS and differently on Android, and you don't usually know them until you actually try it out. An example would be the keyboard avoiding view component. This one we use frequently to basically, whenever you have the keyboard show up, sometimes your view gets blocked. So you wrap your text input with the keyboard avoiding view. But on this one, the styling works differently for iOS and Android. And I think on iOS, we set it up to position or padding versus on Android, you would have to set it up to behavior. If not, it wouldn't even work nicely at all. So these are times when you really need to read the documentation. There's no way you would know what's going on when you test them. I think we got bitten a couple times to realize that our styling had to be changed for Android. 

 

Robin Heinze:

Yeah, always make sure you test on both platforms. Open that PR, I know I've been bitten by that myself.

 

Harris Robin Kalash:

Well, I wanted to talk maybe a bit about the pressable component, because it brings in a lot of... we were talking about how staying true to the native platform, whereas for a long time, whenever we use touchable, it did the same thing on iOS and Android, which was not consistent with the native platform, especially on Android, whereas pressable is really cool because it actually sticks to the conventions of the platform. So you can get a ripple effect with the pressable.

 

Robin Heinze:

What are the different conventions?

 

Harris Robin Kalash:

I mean, there's several things that touchable didn't have at the time, especially, with a touchable, you couldn't really figure out if someone is doing a long press, and you couldn't even be more granular on press in and on press out. These are new props that are available on pressable that we didn't have. The other thing is we never had a ripple effect on Android, so you had to bring in a custom component and the performance wasn't always good when I've tried those, whereas the pressable has a prop. I think it's called Android Ripple. And yeah, you just set that to true and on Android, you get your ripple effect and on iOS, you get sort of the standard experience as well there.

 

Adhithi Ravichandran:

I'm quite excited for pressable too. We haven't really integrated it yet, but I hear it's much more performant than touchable.

 

Robin Heinze:

Is that true about on press in and on press out? I feel like I've used on press in on a touchable opacity.

 

Jamon Holmgren:

Yeah, I think maybe there is but I remember looking at a pressable there's maybe a few differences on the pressable. Maybe it's more precise. I think maybe it's more precise, but I'd have to look at the documentation again.

 

Adhithi Ravichandran:

And I think the long press is definitely a new one.

 

Jamon Holmgren:

Yeah, going back to the previous discussion about some properties applying more to iOS or Android. I work with the React Native WebView and that's probably the biggest surface area for any component, at least that I've seen. It has a huge number of properties. Huge. I mean, it's getting ridiculous. 

 

Robin Heinze:

Well it’s basically an app within an app, it's like a browser, it's like a full browser, which is its own application. 

 

Jamon Holmgren:

It is so you're basically programming this application using props. But a lot of the different properties only apply to one or the other because these WebViews are not equivalent. So you have things like allows fullscreen video, it only applies to Android, because in iOS there's no way to tell it not to, I think that was the reason why it only applies to Android. There are some situations where it just hasn't been implemented for the other platform so it only applies to one. But the bounces, for example, is a property, true or false, but that only applies to iOS, and that's a boolean value that determines whether the WebView bounces when it reaches the end of the content. So just different behavioral things that only apply to iOS, only apply to Android. 

 

Jamon Holmgren:

And this is probably one of the challenges when you have a component that is trying to abstract between two pretty similar, I mean, they're both WebViews. But they're very different implementations with different capabilities and different limitations. We recently dealt with a security implication from... I got a security disclosure from a security researcher where there were some situations in certain versions of Android on the actual user's phone, where it would allow iframes to control the main frame within a WebView. So you have a WebView, you have a website, and then the website maybe has an iframe inside of it, and the content in the iframe could then control the main website, and that was a security problem. 

 

Jamon Holmgren:

So the workaround is not clear, it's not easy. So there's implications for anything that we do, still isn't fixed. Unfortunately, we did the security disclosure, and we tell people how to kind of work around it, but a lot of it is just tell your users to upgrade their OS. And that's just not viable to be honest. So yeah, that's a fun one. That's been a major... and of course, iOS doesn't have this issue, this particular security vulnerability and newer versions of Android don't either, but we're having to work around it now at this edge. So yeah, WebView has been a particularly thorny challenge when it comes to iOS versus Android. Let's talk about the release process for building an app. We talked about this in depth with Gant Laborde in the last episode. But in terms of iOS versus Android, when you're building a React Native app, when you release that React Native app on the iOS App Store and the Google Play Store, what are some of the differences between the developer experience as well as for the user themselves? 

 

Adhithi Ravichandran:

The biggest difference I would say is, it'll take a few days for your iOS app to get approved. So plan for that versus on Android-

 

Robin Heinze:

Or more if they reject it for a silly reason. 

 

Adhithi Ravichandran:

Yeah, just like we talked about earlier, they have a different way of reviewing, they have a physical person actually reviewing your app. So it takes a while. And sometimes you even go back and forth with emails explaining to them why you did this on your app, why it's okay, versus on Android, it's definitely way easier to release the app on Google Play. So time wise, there's a big difference, I would say. And sometimes it goes fast, not to scare you, but it could take a few days. So plan for that. And, of course, the other things would be like if you automate things using Fastlane, like we talked about in the previous episode, you can try to do them across both devices consistently. I'm curious to know what you do at Infinite Red.

 

Robin Heinze:

We use Fastlane for pretty much every app, we usually will have two completely separate scripts, though. So we'll have Fastlane Android beta, Fastlane iOS beta. And then depending on the project, we'll either promote the beta directly to production, or we'll specifically run a production build that kind of depends on whether you have different environmental configs for beta testing versus production. But yeah, we use Fastlane pretty much every project.

 

Adhithi Ravichandran:

Yeah, same with us. Yeah, that definitely kind of conceals a lot of the background things we're supposed to do.

 

Robin Heinze:

Yeah, it's very, very useful.

 

Jamon Holmgren:

We have a guide that Robin and I put together in one of our open source repos. I'll put a link to it in the show notes, but it is basically a circleCI, continuous development, sorry, continuous deployment setup for React Native. It includes things like the past file and the circleCI setup. We even include kind of a beta version of using GitHub actions instead for a deployment. So that's actually probably pretty useful to people if they want to go check it out. We may eventually turn that into a blog post or something like that. We do have-

 

Robin Heinze:

It is a couple of years old. So.

 

Jamon Holmgren:

It is yeah, I guess the last commit was July 21st of this year, but I think that was just the GitHub actions part. So yeah, if there are changes, it is open source, we take pull requests, feel free to help us out that.

 

Robin Heinze:

It is quite a bit more finicky to try and do native or mobile releases using CI, but it is possible. I don't think we ever did it with Android, though, if I remember, right? We automated the iOS TestFlight process but not the Google Play process for some reason.

 

Harris Robin Kalash:

Yeah. One big difference between iOS and Android is in when you have testers, so in testing, Android chooses to run everything through the Play Store. So you have these different lanes, so you have like alpha, beta, and so on. And so you still have to go on the Play Store, and if you're a beta tester, it shows you a little thing saying you're a beta tester. One thing I hate about it is the caching, sometimes I want to get my app quickly but-

 

Robin Heinze:

It can take a day or two sometimes you’ll have clients saying, "Where is it? Where is it?" I don't know. I can't tell you what's cached.

 

Harris Robin Kalash:

Yep. And on iOS, they use TestFlight, so it's not the App Store at all. Sometimes it's still weird, sometimes when I make releases on TestFlight, it's pretty quick. And then sometimes it takes a day and I'm like, "What, the day close at 6:00 pm." I thought the point of the internet was that you don't close.

 

Robin Heinze:

Yeah, I find TestFlight to be just overall an easier experience for beta testing. It's a lot more explicit about the fact that the app is a beta version, there's a much clear delineation between beta and production.

 

Jamon Holmgren:

I'm going to kind of wrap this episode up with kind of an observation, maybe you all can pitch in your opinions as well, but despite all the changes between, the challenges, I should say, and differences between the two platforms, these are kind of on the edge of what you experienced, for the most part, when you're writing components, when you're building things, you're not really thinking about iOS versus Android, you're just building an app. And you can often have both two phones hooked up at the same time, both displaying your app, tapping through at the same time. So our goal when we first moved over to React Native was let's try to have 50% code reuse. Robin, you're the one who's done the most React Native development for Infinite Red here, would you say we've achieved that 50% code reuse?

 

Robin Heinze:

Oh, definitely, definitely. Obviously not including the code that we don't write. There's all the native stuff that comes in with React Native, but of the code that we're actually writing, the components that we're building, I'd say we easily get 85 or 90% code reuse on most of the apps that we build.

 

Jamon Holmgren:

There are even, I would say, situations where we have 100%. There are some apps where we never write any platform specific code. What about you Adhithi? Do you find that to be the same in your experience?

 

Adhithi Ravichandran:

Yes, although we've been going on this whole hour talking about differences, as you mentioned, they're all edge cases. You notice them during release, you notice them across certain native components and styles. But I think on the apps I've worked on, definitely we've have more than 90 to 95% reuse, we hardly have custom code or native custom code. So yeah. So that's the whole point of React Native, right? You don't want iOS developers and Android developers on different code bases. So yeah, for us it definitely achieved that 90% to 95% code reuse.

 

Jamon Holmgren:

Yeah. And Harris, do you concur with that?

 

Harris Robin Kalash:

Yeah, I concur with what everyone said, I'm more curious about code reuse with web. So I hope Robin can shed some light on that when-

 

Robin Heinze:

You'll have to keep tuning in to React Native Radio.

 

Jamon Holmgren:

Well done. Well done. Well, with that, let's go ahead and move into our weird bugs section of the show. Does anybody have a weird bug that they've run across lately?

 

Robin Heinze:

So this wasn't me, but one of the other developers on my project team encountered a bug this morning. It is not a new bug, it's an existing bug but he discovered it for the first time, which is a bug with React Native screens, which if you don't know, is a library that sort of stacks on top of react navigation and changes the navigation stack to use the native screen components, is that right, Jamon?

 

Jamon Holmgren:

Yeah, so how I would kind of characterize it is it's actually underneath, it's actually kind of powering, it's interacting with the native navigation libraries. Because on iOS, you have UI navigation controller and it allows you to build stacks and modals and everything's like that. And on the Android side, you have activities and fragments, which are sort of analogous to screens and kind of groups of screens. A long time ago, I built a library called ProMotion, which uses that was for RubyMotion, but it kind of is on top of the native navigation libraries. And so by using React Native screens, you're getting that same value. So there are a lot of things, these native navigation stacks have a lot of optimizations for performance and memory built into them. And that's what React Native screens gives you.

 

Robin Heinze:

So the bug was essentially, when you're using or when you're building a screen that is a modal type screen, which is a screen that comes and sits on top of your stack, sort of hovers over everything, if you then open the developer menu and try and use the inspector, the inspector appears behind your modal. So you can't actually inspect the content inside your modal, which is obviously a problem because you want to be able to inspect what you're building. So far, there's no fix. I think there was a PR that maybe partially fixed it but didn't go all the way. So it's still open. So heads up if you use React Native screens and you're building a modal.

 

Adhithi Ravichandran:

For our listeners, we should probably post the link so they can see what's going on here.

 

Robin Heinze:

Yeah, we'll post the link to the GitHub issue in the show notes.

 

Jamon Holmgren:

Yeah, hopefully, it's fixed by then. Yeah, this is a kind of a classic sort of Z index depth style arms race because you don't want your modal to accidentally show up underneath something that it shouldn't, but then there are other things that really need to go on top of that. And so-

 

Robin Heinze:

Like the inspector, I think we should probably touch on what the inspector is, if there's anybody listening who's maybe newer. It's a feature of React Native that basically overlays a special UI that lets you click on your different components and you can see what styles are applied to them and what their sizes, it's kind of like the Chrome inspector, if you've ever used that on the web, it shows you the padding and margins and everything.

 

Jamon Holmgren:

It also has things like performance metrics, network metrics, and also it'll I think, highlight touchables on the screen as well, which gives you a little better idea of why something isn't clicking.

 

Robin Heinze:

So it's a really, really important tool for developers. So it's...

 

Jamon Holmgren:

Yeah, totally. Yeah, that is a weird bug-

 

Robin Heinze:

...a nice one once it’s fixed. Yeah.

 

Jamon Holmgren:

Cool. Well, great. This episode as I mentioned before, was brought to you by Infinite Red, check us out at infinite.red. Where can people find you, Adhithi? Where are you on Twitter?

 

Adhithi Ravichandran:

You can find me @adhithiravi on Twitter, A-D-H-I-T-H-I-R-A-V-I.

 

Jamon Holmgren:

And Robin, where are you? 

 

Robin Heinze:

I'm @robin_heinze on Twitter.

 

Jamon Holmgren:

And Harris, how about you? 

 

Harris Robin Kalash:

It's @brunostmamn at Twitter.

 

Jamon Holmgren:

Let's hear B-R-U-N-O-S-T-M-A-M-N, perfect. And you can find me @jamonholmgren J-A-M-O-N-H-O-L-M-G-R-E-N on Twitter. Please do reach out and let us know what you think of the episodes. We are really enjoying doing these since the relaunch a few episodes ago. I've been really enjoying these conversations, but of course we love interacting with our listeners. And you could also follow React Native Radio itself @reactnativerdio, unfortunately, we were one character too long. So we had to cut one of them, after a long discussion, we cut the A. So it's reactnativerdio on Twitter. Make sure to subscribe on your favorite podcasting app. We are in all the popular apps out there. And of course, you can find us at reactnativeradio.com as well. Okay, see you all later.

 

Robin Heinze:

All right, see you. 

 

Adhithi Ravichandran:

Bye. 

 

Harris Robin Kalash:

Bye.

 

Jamon Holmgren:

Thanks, everybody for listening and talk to you next time.