Project Tapestry

Project Tapestry by Iconfactory, promotional image

Craig Hockenberry • Iconfactory

This post will explain the technology behind Project Tapestry and how we tested it as a prototype. We’ll keep this discussion at a fairly basic level: if you’re a web or app developer, you’ll have no problems following along.

And if you think I’m going to describe RSS feeds now, think again! We’ve come up with something completely new.

I’m excitedly looking forward to seeing the final product and I hope they make their stretch goal of bringing it to the Mac. 🤞🏼 Please, go read about Project Tapestry, and if you’re so inclined please support their effort. I backed them early, it was a no brainer for me.

I really wanted to talk about the choice the Iconfactory made to create a highly extensible platform for plugins. It’s a darned great idea! And I love their choice of pushing network requests through Project Tapestry itself as a way to guarantee plugins can’t phish out user data or credentials to exploit later. 👍🏼

As I was reading the post I came across Craig’s mention of the app having a sendRequest method used by the JavaScript code to make network requests. This grabbed my attention and made me realize this is a way better version of a React Native application.

What I mean by that is, React Native is hosted inside a native iOS application framework and uses native iOS controls on its view controllers or its version of a view controller. The JavaScript code drives everything from networking to user interface (it uses UIKit internally) to render content for the user to interact with. This allows developers to write their app using straight web technologies and run it on iOS and Android.

The project I’m currently involved in is an existing eight year old iOS application built with a mix of UIKit and SwiftUI. On the flip side the Android app of the same age is built using Java and Kotlin with a mix of the original XML based UI and modern Jetpack Compose. They’ve both taken very similar and not unexpected paths.

Enter React Native

Something our client wanted to do is integrate React Native into the existing applications. This has been done before by Airbnb and more recently by Shopify. Each with very different outcomes.

So all of that to say, ours has been successful, in my opinion. We’ve been able to fully integrate React Native and carve out a little set of API’s in the native application we expose to the React Native developers to do work the native application is already doing for them for free. Part of which is all the networking calls.

In the Tapestry blog post Craig points out sendRequest. It’s the call they use to handle requests to the internet for the JavaScript plugin. In our application we’ve exposed a makeRequest call that handles doing any type of network request; GET, POST, PUT, PATCH, or DELETE, and returns a Promise to the caller. Hey, sounds like the Tapestry code! 😄

I have it on my todo list to learn JavaScript. It’s been there for years and years because I knew I’d need it at some point. I really need it now. I can’t see React Native projects going away for the WillowTree team. They’re a very popular way for our clients to get cross platform code and get an iOS and Android app out the door simultaneously without having to spend time, money, and effort on two completely separate code bases.

Over the course of our integration work I’ve done a smidge of TypeScript code to allow other TypeScript devs on the team to make calls into the APIs we’ve exposed in the native application.

It’s been fun and I see a place for JavaScript/TypeScript in my native development world.

Project Tapestry is BETTER!

As for what Iconfactory is doing, I think it’s a much better version of what React Native does. It gives them the best of both worlds. A beautiful, hand crafted, fully native UI, that gives JavaScript developers the ability to extend the app. That’s a lovely thing. ❤️

React Native Impressions

RibbitI’m on a project at work using React Native but not in the typical way, which is to say it didn’t start as a React Native project. It’s an exiting app out in the world actively uses by, I’d imagine, tens and tens of thousands of people. Perhaps hundreds of thousands. Bottom line is, it’s a frontline app and is important to our client.

Our client has a large team of React developers and a team dedicated to the design and development of reusable React components for the company. They’ve done an amazing job creating a platform for their devs to build on and would like to have those devs build mobile experiences as well. I can’t blame them. They’re very good at it.

They currently have native iOS and Android apps that are almost ten years old and use various frameworks and technologies. Your typical legacy codebase. That’s nothing new or frightening. All code develops its rough patches over time and as time goes by we go in and turn the soil so to speak. We replace outdated frameworks developed out of necessity with new platform supplied frameworks and our code is more robust and easier to read and maintain, especially for developers coming right out of school.

Brain in a jarWith all that in mind here’s what our client is looking to do. We are building new features in React Native and leveraging much of the internal native code to fetch network data, build models, and return that data to React Native code. The API or Interface to the native code is well defined and implemented on iOS and Android. The React Native team code is the same for both platforms. I’m part of the platform team integrating React Native into the existing app and providing the API/Interfaces to the React Native developers.

Like I said, this is a non-standard way of doing this but it’s been done by others with stories of success and failure. I believe we are on track to have a story of success. It’s not going to be free of bumps along the way but we’re making really great progress and I believe we will hit a steady working state as soon as next week. That means the foundation to strap up and host React Native code is in place and working as expected. Now it’s time to build out the API more thoroughly, driven by our React Native developers need for specific data or business logic. It’s a single app, purpose built, API. The idea is to hide any ugly code on the native side and keep the API to the app clean for the React Native developers.

Cool Bits

One of the extremely cool things about how we’re approaching it is how our React Native devs work.

They work inside of a separate application while they’re developing new views and logic. It allows them to move more quickly and not have to rely on the native apps to update before writing their code. It also means they don’t have to worry about keeping the existing native app building on their computers. That can be a headache, I wish it weren’t, but it can be. More on that in a bit.

How does it work? Well, when you create a brand new React Native project you run some tool to generate the project for you. It creates the scaffolding for your React Native code as well and iOS and Android host app projects complete with the frameworks necessary to build the native host apps. On iOS uses CocoaPods. I don’t know what Android used.

That allows the React Native Developers to run ahead of the platform native developers to build their UI’s.

Ok, so how does that work?

We negotiate with the React Native development team to define an API signature for the native apps. They build a mock version of that in their development host app that matches the agreed upon signature and go about coding.

We build out the platform side to do the true implementation. When we have something to test we pull over a packaged version of the React Native code and give it a spin. If there are problems we work directly with the React Native developers to figure it out. Once it’s ironed out it’s wash, rinse, repeat. We currently have a feature built by WillowTree and one built by our client working in the development host and in the existing native applications.

It’s pretty darned magical when it works! 🧙🏼‍♂️

The Ugly Bits

Getting the React Native frameworks and nuanced build settings and scripts in place has been a bit of a struggle but I think we may finally have all that figured out. But it is painful for a native developer who’s used to opening Xcode, loading the project, hitting build, and it runs. Sure, we may have to use CocoaPods to get started, but that’s rare now since Apple introduced Swift Package Manager, or SPM.

SPM is integrated into Xcode and works really well. I’ve never had an issue with it, knock wood, and went through Stream a couple years back and replaced my use of Carthage and CocoaPods with SPM. It’s been glorious.

This option is, unfortunately, not available to React Native projects AFAIK. That’s fine. CocoaPods works and is familiar.

AHHHHHH!The one really ugly bit, at least to me, is the requirement to use npm. I know web devs are accustomed to using it but it feels really strange and fragile to use these two package managers to be able to build and run an app that includes React Native. I know I’ve run into random issues I can’t explain when node packages change or are added but that’s just me being a big whiny cry baby developer. I understand it well enough to be dangerous but I don’t currently have that deep knowledge I like to have. I’m learning new stuff everyday but I’ve only scratched the surface.

Great! How do you feel about it overall? 🤔

Red sock.I can see why companies are making this choice, especially companies with an army of React developers. It makes complete sense for them to build great UI with their existing developers. And, yes, you can build a great iOS UI with React Native. I’ve witnessed it first hand. If you didn’t know a view was React Native you wouldn’t know the difference in this app. It’s seamless. It’s great in that way.

Angelo Stavrow

but oof — it still feels like I’m working with a business decision, rather than a sharp tool.

I think Angelo’s quote above is a nice TL;DR for me. On the downside I really dislike the tooling. It feels so arcane. I’d love to see something integrated into the Xcode UI for package management and project settings. That’s probably asking a bit much but I’d rather have some do an amazing job of all this scaffolding so I can just hit the build button to run the app.

All that said, it’s still worth using. 👍🏼

The New Mobile Developer

Welcome to the modern definition of a “mobile developer.”

If you know JavaScript you’re golden. It’s no longer about native apps, it’s about leveraging web tech, and getting the most bang for your buck.

Learn the JavaScript if you want to have a job moving forward. Personally, if I were to use a cross platform development platform I’d probably choose Flutter.