Hacker News new | past | comments | ask | show | jobs | submit login
Ask HN: What do you regret you didn't know when programming for iOS or Android?
237 points by toron123 27 days ago | hide | past | web | favorite | 159 comments
What do you regret you didn't know when started programming for iOS or Android?

I'm a self taught programmer and started developing for Android in 2012. It took me a while before I realised that you needed third party libraries to do absolutely anything useful as the platform APIs were so poor and undocumented. There were gaps everywhere and you needed to write tons of boilerplate code to do things properly.

Image loading was often a huge source of crashes due to out-of-memory errors and doing it properly wasn't trivial [0]. Libraries like "Glide" and "Picasso" solved this.

Using the camera hardware was awful. Device manufacturers would implement things differently, and break the camera API unexpectedly. Only recently [1] are we starting to see sane, consistent camera APIs.

Making network requests felt extremely clunky, and the platform JSON implementation wasn't performant, or easy to use as you had to manually parse everything. Retrofit [2] made talking to REST services much easier.

I could go on and on, but I'm sure there's plenty others here who can do that here. These days Android development is much, much more enjoyable. Kotlin has pretty much replaced Java in the Android ecosystem, and there's great reasources around on how to architect your app to make everything testable and easily scalable such as the architecture samples [3]. I've worked on a few React Native projects in the last year. I'm not a fan of it, but I definitely see the industry heading to some cross platform solution eventually.

[0]. https://developer.android.com/topic/performance/graphics/loa...

[1]. https://developer.android.com/training/camerax

[2]. https://square.github.io/retrofit/

[3]. https://github.com/android/architecture-samples

Personally I think that Flutter is the future for cross-platform UI toolkits. As a React dev (in my spare time, I’m still a student), using RN was a pain due to the need to install native extensions for almost everything. The batteries-included approach of Flutter and just the polish around the dev workflow made it more attractive to a beginner mobile dev.

I would be hesitant to recommend seriously pursuing cross-platform. Most serious applications generally run into scaling issues as they get more complicated and demands require more than the abstractions the cross-platform tool can provide.

On the other hand, very few applications need to scale to the point where it matters. If the options are "ship something now and refactor later" versus "ship something in six months that's perfect but too late", most people here would benefit from cross platform solutions.

Very few companies have ever failed because their tech stack didn't scale well.

This is a nit, but there's a pretty big difference between refactoring and rearchitecting.

If you plan for an eventual migration of the app from a cross-platform toolkit to native, then often you're committing to a significant rewrite of the app. This means either you dedicate a team to the rewrite or you stop adding features while it gets rewritten.

Plus it will take a while for the native version to get feature parity with the cross-platform version, and you typically can't roll out the native version until you have parity.

I'm sure there are tools and strategies for getting this right, but I've seen this basically kill startups.

> “I'm sure there are tools and strategies for getting this right, but I've seen this basically kill startups.”

Well if they're doing it like that, it's indeed not much better than hara-kiri. There are better ways :)

How you do it is incrementally, avoiding too-major changes at once, and progressively moving from codebase A (cross-platform framework) towards codebase B (new native thing). But it happens at the integration level, i.e. you build with increasingly more % from B, but during the whole A->B transition it'll be a hybrid build.

E.g. part Flutter / part native.

1. You begin with "let's take camera stuff out of Flutter and re-implement our related features using native APIs": this instantly makes two apps (iOS, Android) with 90-99% code in common, just a fork to handle camera APIs separately (by the way, the state of API affairs often forced you to do this to some extent for any non-trivial use-case; I'd wager it used to be the state of most feature-rich apps in the 2010s).

2. Then you proceed with another component of your app. Rinse and repeat until you've got 90% from B and the remaining stuff is structural.

3. All that remains is to remove Flutter entirely from the equation and rewrite your core app logic: what glues all of the above components together; all of which at that stage are already rewritten for native and tested independently (critical to your success).

Along the way you never truly break UX, it's more of a classic "ongoing development" thing with details changing here and there, and hopefully better UX each step since your move to native must be motivated by something worth it for the client-side (otherwise it's likely your server API model that needs refactoring).

That's how the now-default-consensual approach to how you change stacks without breaking UX, nor your company. Full rewrites on wholly new tech is just asking for cataclysm: you literally do that to yourself, to your own code and users. It's also the only reasonable way I know for small teams, one-man shows, etc.

Make sense. And may be should start with this thinking when I started to avoid the first pain.

You're right, I didn't use the correct terminology and I appreciate the correction.

On the other hand, using information from Facebook themselves (creators of React Native), the cross-platform solution seems to be able to scale pretty darn well [1]. Facebook, Instagram, Bloomberg, Skype, Walmart, Uber... these are some pretty big names with some pretty big audiences. If React Native can get your company from a startup to the size of any of these companies, I'd say you're doing pretty well on the technology front.

Kind of like how Twitter had to do a major rewrite from Rails, but Rails got them to the point where they needed that rewrite.

[1] https://facebook.github.io/react-native/showcase

I think you'd indeed have to look at more demanding applications, more "bleeding edge" stuff computationally: 3D gaming is probably as good a candidate as ever, maybe some in-app AI workflows, idk. Truth is, I know how to bring a desktop/server to its knees because there are valid use-cases for that, but on mobile I struggle to find many examples indeed. I guess any heavy data crunching app might fit the bill, but when don't you run that remotely? On-premises offline pro apps maybe, like tools for e.g. plumbers and electricians? All of that stuff is in embedded afaik. Dedicated devices, rugged cases, it's a whole other market/target.

So cross-platform solutions on mobile indeed seem to fit most-if-not-all of the 'normal' use-cases, assuming there's server resource available. The Twitter/Rails example is one perfect illustration, and there are many such examples throughout big names we know today.

The issues you tend to run into with mobile is that you have to either create so many shim layers to use native app features or resort to 3rd party solutions. And there are loads of examples (speaking for iOS here):

1. JSON parsing

2. Network calls

3. Background downloading

4. Notifications

5. Camera access

6. Password/contact/code auto fill

7. VoiceOver

8. Web Views

9. JavaScript bridging

10. Encryption

11. And many more

Almost every app needs some combination of those and in some of these cases you’re forced to use a native solution. What ends up happening is that a significant amount of developer resources gets wasted bridging many of these things with massive bug logs to go with them. It’s why at this point I refuse to do anything but native in my career.

> “It’s why at this point I refuse to do anything but native in my career.”

Point well taken! If I may ask, would you say that

1. it's a problem inherent to developing on mobile (whatever the underlying reasons, hardware iterations, idk), and that OS APIs are indeed trying to solve as best they can (it's just a hard problem),

or rather

2. that it's a problem somehow created by OS vendors of their own volition? (a.k.a "evil microsoft walled garden", cue "Apple's take on that" and Google's similar moves for Android and we think Fuschia) In essence a business-driven reality.

I actually don't care about "evil" (hence the wording, it's funny) when it's just business strategy; my deeper question is really about the problem space.

Like, is this forever (native versus cross on a fast-iterating platform), is this industrial politics or technical limitations, could some other platform do it "better" (thinking of SailfishOS, or the Linux phones like the Pine project etc.)

> Very few companies have ever failed because their tech stack didn't scale well

Just out of interest, are there any clear examples where this happened, ever? Can anyone name any?

What I mean specifically is - a company with a well known product that was growing in popularity but then hit a ceiling because of technical scale issues and couldn't support any more customers, growth halted, and they couldn't fix it in time to keep the momentum going (or got overtaken by a competitor) and failed?

It happens all the time. When it does, though, the narrative is usually "scrappy upstart takes over" and not "segment leader fossilizes".

So what would be some examples of when a scrappy upstart took over because the segment leader ran into tech stack scaling issues? (As opposed to the segment leader running into corrupt or incompetent management, failing to notice a new market opportunity etc.)

Today is a weird time to get into mobile app dev. The standard 'native' UI frameworks are pretty terrible in terms of how they cope with complexity and their ability to change over time with their dated OOP APIs. Though on both platforms the tooling has been climbing ever upwards towards local maxima.

The best options available for most Apps today (even if just for a single platform) are typically React Native or Flutter. With their React(-ish) UI approaches you can both quickly build and iterate in the future.

SwiftUI is not ready for most uses (I've shipped a small but non trivial app https://apps.apple.com/us/app/pattern-maker/id1484249212 and was surprised by how many bugs there are for very standard things and how many hacks seemed to be required). Jetpack Compose seems to be at an even earlier stage. I expect both will be great but probably not for some time.

For those into gamming the standard native UI never mattered.

Then there are several kinds of workflows that are quite doable as mobile Web. One just has to take into consideration that 3G isn't broadband, nor a mobile display a last generation 25" screen.

There are plenty of "serious" applications written with cross platform tools. Flutter, React Native even ionic/cordova - it depends entirely on what your application does.

Flutter is DOA for anything but short-term projects.

For one thing, it’s tied to a custom language. That means there’s significant overhead for developers which shows itself directly as a learning curve, or indirectly in terms of hiring or retention of developers.

At least as significantly, they chose to implement custom controls (rather than wrap native controls). With that approach there’s really no way for them to implement native expectations for controls in the first place, much less keep up with native functionality across platforms.

I disagree strongly with this.

I'm currently writing a cross-platform app in Flutter that is launching soon, and I found that the developer experience is world-class and I've had very few issues so far. The language is incredibly easy to pick up with close to zero overhead if you are a somewhat competent programmer as it is essentially a very lightweight OOP language. My main languages are otherwise Go and Rust, and picking up Dart was not difficult at all for me and I don't think you need to be a wizard to figure it out. I suspect JS devs will find it even easier to pick up as many of the constructs are similar.

It took only a couple of days to get up to speed with Flutter-specific functionality as well as the native API bindings, and I was already writing production code for the app the first week of exposure to the language. The UI framework is declarative and very easy to reason about and design, and the tooling is also incredibly seamless and easy to use, although I do agree that it needs some polishing as there are some edge cases that you sometimes need to trawl the Github issues page to fix.

Yes, sometimes it is frustrating as there are some things that are lacking in the standard library, but the third-party library scene is picking up and you can do 95% of what you want to do without major issue. I'm convinced that Flutter is going to become bigger in the future and is going to cover most use cases for all but the most performant apps and perhaps games.

To follow on this, I've had more "wow" moments with Flutter than from any of the tech stacks I've ever worked with.

Flutter is a breath of fresh air after building and maintaining the same app over and over again for several platforms.

I've released two Flutter apps on Google Play and I don't see Flutter in such pink colors. Every SDK update makes some users change their ratings because the app starts crashing for them, even when I'll make trivial changes. Cupertino theme is bugged on Android. Flutter team is OK with doing breaking changes to widgets, so when you update, prepare your self that you may need to rewrite some parts of your app, because some widget has changed, etc.

Flutter will be to Dart as Rails to Ruby, if the political wars between Chrome, Android and Flutter don't kill it first, that it the only thing Dart will be relevant for.

> For one thing, it’s tied to a custom language.

Are you talking about Dart?

If so, that's absolutely savage, lmao. To not only call it a "custom" language but not even name it. The amount of disrespect - and the worst thing is I don't even think it was intended. Even if this is one person, I think this speaks volumes about how much of a joke the language is.

It's just so sad. And to think that the team behind flutter purposefully chose it after considering a bunch of other languages.

Well they did add the compiler half way through.

You can write idiomatic Dart code that won't run because Flutter asserts crash it at runtime. And you fix it by writing code that the Dart compiler complains about but lets you run and it works (even though it shouldn't). Is there another compiled language where this is the norm?

What's the point of dealing with a half baked ecosystem when there are much better languages available?

I don't think he meant it that way. He's probably trying to say that depending on a "custom language" is a bad thing in itself.

I personally don't feel that dart is tied in any way to flutter. It was originally meant to be compiled to js, and that shows in vm architecture, but that doesn't look like a con.

I bet that Chrome and Android team would have more political muscle than the Flutter team.

PWAs will keep being pushed by Chrome team, alongside Microsoft, and I wouldn't be surprised to see a Kotlin/Native variant of Jetpack Composer by Google IO 2020.

Perhaps Xamarin is a good choice as well for who want to transition from development of desktop apps. Also support for F# on Xamarin is also a plus.

I was waiting for someone to mention Xamarin. :D

I haven't worked with the platform for 2 to 3 years. In my old job we had massive problems at the end hence we switched to native (we were an agency).

Problems we had:

* Deploying to devices was painfully slow compared to native stack.

* We all had Macs and the tooling (Visual Studio for Mac/MonoDevelop) was pretty bad compared to Android Studio.

* Wrapping 3rd party native libs was a pain, if not impossible. Especially in a stressful agency environment.

When we heard about the acquisition of Xamarin by Microsoft I was hopeful things would change to the better. But month later they rebranded MonoDevelop and focused on integrating Azure.

Did it get any better?

Visual Studio for Mac has suffered quite a refactoring after the acquisition, as many of the MonoDevelop internals have been refactored into common libraries shared between Visual Studio and Visual Studio for Mac, one of the reasons why the new plugin infrastructure is based on .NET instead of COM.

There a release event happening next month, https://visualstudio.microsoft.com/vs/mac/event/

How is flutter's open source widget community?

>Even Google's own Pixel devices do not support this. The image quality from CameraX API is not ass good as the stock camera. And there is no support for Night Sight. I do not get this.

From the comment 2 months ago https://www.youtube.com/watch?v=QYkTXJ2TuiA&lc=UgwBlx_R3eL4k...

I should’ve known that it’s turtles all the way down. Considering how many years I’ve sunk into programming for other platforms, this shouldn’t have come as a surprise, but I got suckered into believing that mobile computing platforms represented a significant enough paradigm shift to allow for starting with a cleaner slate.

Not true! Having gotten into iOS development over the past couple of years, I’ve come to realize that seemingly no attempt has been made to actually clear the cobwebs on this shiny, relatively new platform.

For example, SwiftUI is just an abstraction layer for UIKit, which itself is (keep me honest, HN) an abstraction for some mishmash of Cocoa, Display PostScript and Metal. Bits of NeXTSTEP are everywhere still, even when using Apple’s latest and greatest programming paradigms.

Don’t get me wrong, iOS is great, and I love it to death. However, the baggage signals to me that a massive opportunity to start anew has been missed.

> Don’t get me wrong, iOS is great, and I love it to death. However, the baggage signals to me that a massive opportunity to start anew has been missed.

Starting anew is over rated. It’s sometimes the right answer, sure, but it’s just one possible answer. iOS benefited enormously from being immediately familiar and approachable to existing OSX devs, and would have taken another 5+ years to develop from scratch without leveraging its OSX heritage.

Meanwhile Android was in a crash emergency race to relevance for the first 5 years of its existence. If they’d taken the time to do everything right the first time, they could have ceded Microsoft enough time to get their Windows Mobile act in gear.

So legacy is a thing for a reason, taking one opportunity very often means giving up another.

I think certain paradigms were completely shifted compared to the PC space.

  -Revamped permissions
  -App packaging/name spacing/consistent installation
  -IPC was redesigned as asynchronous Intent blobs on Android
  -Urls becoming first class citizens at the OS level
  -More consistent background app apis (and eventually better ways to track them)
I could come up with more but I think there's actually a very big difference. But yes, its all built on top of older Java and obj-c libs.

SwiftUI isn’t UIKit-specific. Display Postscript hasn’t existed since the OS was called NeXT, 20+ years ago, and was never on any iDevice. Cocoa is an alias for AppKit + CoreData, and iOS uses CocoaTouch instead.

You’re right, yet this doesn’t directly address what parent said, in fact it’s somewhat agreeing with the point, that there’s a ton of influence left behind by these things, even though they are not there anymore.

Display PostScript is in Apple Mac OS X Server 1.0 and then abandoned in favor of Quartz and PDF.

> Don’t get me wrong, iOS is great, and I love it to death. However, the baggage signals to me that a massive opportunity to start anew has been missed.

I guess that's what Flutter is doing (for both iOS and Android).

> I guess that's what Flutter is doing (for both iOS and Android).

How does it do this as opposed to adding yet one more layer? Does it somehow get beneath all the cruft mentioned?

It is another layer, but it has as small as possible dependence on the below layers (UIKit, OpenGLES, posix) and instead tries to reimplement everything. For instance, if you want a slider control, that’s not going to use UISlider underneath, it’s going to reimplement it from scratch.

The problem with this is that it is an enormous task and they have barely scratched the surface of it.

Flutter is hardly the first reimplement the world GUI programming environment that tries to match the existing first party environment in terms of look and feel. Java swing was pretty much the same idea 20 years ago, and probably had more investment and momentum behind it than Flutter does today. While I can think of a number of swing success stories, I don’t think java swing as a whole was successful in what it set out to do.

> The problem with this is that it is an enormous task

It's an enormous task that never ends, too. Flutter has to continually keep up with UI/UX changes that Apple makes. Without enough momentum there, the devs using their platform are going to have apps that appear/feel old, which tends to be a marketing negative for Apple users.

Flutter took the approach of treating the screen as a blank canvas. Everything is drawn using Skia primitives, exposed as Dart libraries.

It has some downsides – they had to expose a lot of accessibility features on top of that using platform APIs – but it's quite nice when you are a developer, as you can Cmd-click on anything to learn how it is drawn, and use the same tools to build your own widgets if you need.

Afaik Flutter is basically a Game Engine. Its not using the build in UI Toolkit instead rendering everything itself and just mimics the look of the native UI.

I'm not completely sure about it, i just now it from listening to some talks.

Yes. It's not using any native UI widgets or UI code, but drawing everything itself using the lowest level API it can get, which I guess on iOS is Metal (and something for input). This means that the look and feel and the behavior and accessibility features will not match those of other apps (which do use the native toolkits), or the Flutter team will have to do a lot of reverse engineering and re-implementation to match that on each platform.

Currently, Flutter targets OpenGL ES on iOS which is less than ideal.


"We were discussing this in today's Triage meeting. Our current plan is to turn Metal on soon. This will increase the size of our engine by ~200KB. We can eventually reduce this by removing the OpenGL code but (a) that would drop support for <iOS10, which we don't want to do anytime soon (Skia only does Metal from iOS10), and (b) would require some work from the Skia team (OpenGL can't currently be removed from the codebase)."

Seems like it will be solved 'soon'

I am really curious why you are concerned at all about supporting iOS 9 (and lower?) at this point. That's a tiny, tiny fraction of worldwide iOS users. Probably not more than 1%. How many people are creating apps in Flutter that need to target that far back, and that user base?

Besides being a cross platform platform for Android and iOS, it appears to be a native UI framework for Fuchsia, Google’s nearly ‘from scratch’ OS.

I consider this a feature: the older code has known behaviour, while a from-scratch implementation would have been a minefield of unknown bugs

I’m not buying your reasoning. Try putting a WKWebView into a SwiftUI view. This kind of thing is all sorts of messed up when multiple rendering systems - two of them declarative (SwiftUI and HTML) - collide in a single view. I’m sure someone’s going to call this a corner case, but useful and interesting apps that push the boundaries of the feasible are all composed of such “corner cases”. And hey, I’m not even doing anything outlandish: just trying to show some HTML.

I sympathize with your position and have had similar problems in the past. There’s no magic option. But typically the combination of a completely new API and implementation is very difficult for both implementors and users.

It depends somewhat on why you ask.

A lot of people are recommending using cross platform solutions. As a hobby or learning exercise, go for it! As someone who has a career across many projects working full time as a native iOS and Android dev, I can say these solutions are generally avoided. They are good for prototypes you don’t plan to maintain long term, I’ll give them that.

I know it’s cheesy but my only regret is I didn’t go all-in on mobile sooner. I have been on a constant upward career trajectory since the day I put my first app on the store. Get an app on the store as soon as you can and if it gets traction listen to feedback and update it. If you’re early in your career this will be the only thing on your resume that matters. I highly recommend you start with iOS just because the tools are more friendly for beginners. Watch WWDC/Google IO sessions and keep up with the latest. However it’s best to keep a healthy distance with things that only support the newest OS. For instance I wouldn’t build an app in SwiftUI yet but I follow it like a hawk because it’s likely to be the only way Apple platform apps are made very soon. Closely follow VR/AR frameworks and machine learning. Those will become must-know this decade.

Mobile dev is so rewarding! Every developer should at least dip their toes in.

As a front end dev I’ve been thinking about it for so long but honestly I don’t know what I should build or study first.

It’s always best to work on something you’ll actually use. Maybe think about an app you already use but want to improve or simplify (a to-do list without the frills for instance).

As far as learning, I think this Stanford course is the best way (though not for those who aren’t absolute beginners to programming). I notice it hasn’t been updated lately but it should be current enough https://www.youtube.com/watch?v=TZL5AmwuwlA

I wish I would have not fought the tools so much.

I started Android programming from the command line using make/ant and testing on a device because I didn't like Android Studio. This ended up wasting a lot of time and energy over the years as I had to integrate more 3rd party libraries (including Google's own crap).

Same thing for iOS. I didn't like building GUIs in Interface Builder so I did everything in code. Over time as iOS devices came in different sizes, this became harder to do properly. I should have given in early and learned to use Interface Builder, auto layout, etc.

I've been doing iOS for a while and I also fought AutoLayout for too long. I found doing it in code better than trying to get IB right, especially when working on a team.

What do you think about SwiftUI? I never liked coding layouts by hand but it seems a great compromise for SwiftUI, so I'm pretty happy to use it later on when more devices have moved on (which should be soon)

Code-only purists are still prominent in the iOS community. Yeah, there’s definitely baggage one must take on when using IB but the ease of being able to instantly preview your layout in different sizes is the big seller for me.

I actually went the other way. With autolayout is just easier (for me), to do UIs in code. Especially because IB does not offer 100% of what UIKit has. I don't hate IB, it just become less relevant to me. Storyboards on the other hand… Never thought well about them.

most large apps, build by large teams, (from large companies) don't use IB at all.... for many reasons, but the main one it just doesn't play well in a 'many people working at the same codebase' type of environment.

For smaller apps, with a team of 2-3 people, IB is fine....

IB files are essentially impossible to code review.

If you read the storyboard diffs the layout code is human readable, just need to get used to it. Although there is no docs

Not in the case where a bunch of views are moved inside a new view. Then the XML diff is really janky, and elements are assigned new IDs.

The constraints are impossible to code review in XML since they refer to elements by IB ID which is essentially obfuscated. I don't understand why IB doesn't let you give the elements their own human-readable IDs.

I’m not against IB but the lack of stuff like constants is really difficult when a customer demands “same app, different skin”. SwiftUI seems to fix this.

That developing for Android isn’t even as half as smooth as developing for iOS. Yes, with iOS you’re using Xcode and have to set up provisioning for your dev device and all that, but once you’ve done that you’re mostly on your way. UIKit, while not the shiniest thing out there, is quite competent and functional — you can easily write world class apps with it while keeping third party libraries to a minimum.

On Android, setting up for development is a bit faster but the actual development story is so, so much worse. Kotlin improved things a great deal and Jetpack improves it further, but it still has such a long way to go. You’ll spend inordinate amounts of time researching the “right” way to do things only to find that there really isn’t one, but instead several ways with varying levels of wrongness with different trade offs. Even mundane things will be a source of trouble and you will likely have to make concessions in your UI design to work around Android SDK awkwardness.

If I could just have UIKit on Android I would be a much, much happier Android dev. Hoping Jetpack Compose improves the situation but I’m not holding my breath.

> You’ll spend inordinate amounts of time researching the “right” way to do things only to find that there really isn’t one, but instead several ways with varying levels of wrongness with different trade offs.

From what I've heard Android is unusually bad for this but this particular sentence resonates with me in terms of basically everything ... though that may be because I do a bunch of deployment/ops stuff which is generally entirely made out of "choose your own petard to be hoist by later"

The best-case end result of this instability, of course, is the "double interface" - an interface abstraction on top that talks in terms of the domain problem, and then a second layer to convert the lower level interfaces into that abstraction.

Unfortunately GUI is particularly fiddly and difficult to write the double interface for, since you get a "thousand words is one picture" problem: it doesn't reduce well to text.

The thing that would've saved me the most time and frustration in the long run for all mobile development (well, all dev period, but mobile especially as they tend to be moving targets):

Ignore the framework. Write your app how you want to write it, then attach it to the framework as needed. Don't restrict yourself to what the framework supplies or how it thinks about things.

It'll dramatically decrease craziness in your core logic in the long run. Framework versions and bugs can lead to strange lifecycle callbacks, weird interactions between the N flavors of how to build UI components, etc, and if your core logic is chopped up to deal with all of this it can become very hard to make important changes. Such as updating to a newer version of the framework so your app isn't removed from the stores.

It'll pretty much always be more up-front code and work, but you'll be left with a far clearer system in the end.

Related to this is “clean architecture”. Your code should not be dependent on a feature-laden framework. You should focus on writing your business domain and rules, then separately orchestrate your domain, and connect the UI and other external frameworks as interfaces to the lower, or more generic, levels of your application.

This is a general software design principle that allows for your UI to be free to change without affecting your core logic and rules, while also making all of your code more unit testable.

With React hooks or android component life cycle its hard separate the framework and logic. How do you do it ? Any recommended books or other resources ?

React's behavioral features are relatively difficult, I'll grant, but it's entirely possible to use it as a relatively dumb "render X efficiently for me" target. If you're using hooks heavily, you're deeply entangling your code with the framework - that's your choice, but yeah, it comes with consequences as well as benefits.

Android lifecycles are probably the main target of my comment tbh. They're abysmally complex and make any kind of state management incredibly error-prone.

As a tradeoff for that complexity and losing a lot of control, if (and only if) you go all-in on them, you get decent state reviving after process death, which can do really slick things like "app crashed" -> it just appears to go back one screen.

Instead, you can write your app as e.g. an in-memory singleton somewhere. You can even do that in a different thread if you want, leaving your UI impossibly smooth (at increased risk of "tap x" -> "nothing happens"). Design your own lifecycle that makes sense for your app (which probably looks very little like the Android lifecycle, especially when you throw in fragments...) and trigger/wait on the external world of the Android framework as needed. Odds are pretty good that you'll take multiple things from Android and combine them into one in yours, and potentially vise versa (e.g. multiple actions from your app become view updates in a single activity, rather than multiple activities. or do everything in one activity, it's often far better performance anyway, and much easier to control in fine-grained ways. importantly, your core logic doesn't care, unlike if you put that logic in the activities).

I regret not knowing about cross-platform development such as Flutter and ReactOS.

I also regret not buying a book explaining all the concepts in as simple a manner as possible. As a semi-amateur programmer, I feel like most of the documentation is meant to refresh the memories of people who have been developing apps for years; they're extremely beginner-hostile.

> I feel like most of the documentation is meant to refresh the memories of people who have been developing apps for years; they're extremely beginner-hostile.

Yeah, really agree with that; I'm not sure about the state of Google, but the word 'beginner-hostile' is really an exact state of Apple's documentation (well I'm touching AppKit not UIKit, so that's a factor too but...).

Coming from a web background, almost every web framework had a starting point from the documentation or at least some concept documents: Apple's documentation is almost non-existent. The best documentation I could find was the archived ones from early 2010s, and those were not really helpful at all.

I did know Apple's dev experience isn't really great... but what I did not know was that learning Apple's APIs/conventions means watching three and four WWDC videos that briefly touch the API for about two or three minutes, learning two languages together(Swift & Objective-C -- which actually wasn't really that awful for me b.c. I already knew much about ObjC & message passing due to my interest in various (elegant) PLs), & searching for other people's personal projects from GitHub.

Seriously Apple, improve your documentation. It's just plain awful.

It’s really sad as Apple’s “Inside Macintosh” documenting the 1984 Mac was fantastically good and readable, very enjoyable to read.

Can you give an example of beginner hostile documentation?

Agreed. This absolutely kills me when people say “just read the documentation” or “the documentation is very good” as a reason why they don’t produce examples or templates or starter kits. Not all of us are CS majors or programmers in large teams or with decades of experience to fall back on. Just reading the documentation isn’t enough to get me into a new framework or language. I need to see practical examples.

For mobile development, this is why Expo was so crucial for me to understand how React Native works.

Apple used to have a lot of pretty good (not perfect, but pretty good) conceptual/architectural documentation. Most of it has sadly been sunset, and is hard to find, even though it's still largely applicable. And it hasn't been replaced -- hopefully that's just "hasn't been replaced yet".

Apple documentation in the 90s was a piece of beauty. Microsoft's was pretty good too back then with MSDN Library CDs.

This is so true and so sad. It was so good!

> I need to see practical examples

And I need to see diagrams of mental models, though practical examples help solidify that. So one challenge with writing documentation is knowing what your audience needs. A better taxonomy of documentation would help solve this. For now, here is one I like based on https://www.divio.com/blog/documentation/

- Tutorial: A walk through how to learn the basics as you build something.

- Explanation: Showing the mental model of something

- Guide: A walk through how to solve a specific problem

- Reference: A comprehensive* listing of the API capabilities and how they are used.


If anyone knows of some good tutorials or explanations of mobile programming with React, I'd be grateful for recommendations.

Apple seems to be particularly bad for this, I was going through some of their videos recently and everything assumed prior knowledge. It's the same for much of the documentation.

As much as I criticise Microsoft at least they have stuff like this: https://docs.microsoft.com/en-us/windows/win32/learnwin32/le...

To be honest, I think you're being too generous.

The problem isn't that they're providing documentation which is good but only appropriate for a narrow audience. The documentation is just bad: it misses out things that need to be said.

React? ReactOS is the open source version of Windows NT

They probably mean React Native

Wild how few on here note this as an error

To be fair, most cross-platform projects have been total garbage (PhoneGap, Titanium, etc.) Sadly the only one decent was .. Unity, which is why you'll sometimes see things that aren't even games written in it for mobile.

I regret not knowing that Android API is awful.

Then I regret looking into Nativescript, because it was pretty buggy.

Then I regret not knowing about Flutter earlier.

THEN I regret not knowing that Flutter is pretty buggy as well.

Next step is me trying to learn other frameworks, like Cordova or React Native. I wonder what my regrets will be.

Flutter is quite good, what were some of the issues you experienced?

The one PITA for me is state management, but once you understand how to solve that using BLoC or Providers then it should be relatively usable

Well since you ask: Flutter is good, but it's also buggy.

1. Problem with Cupertino theme on Android - https://github.com/flutter/flutter/issues/42988#issuecomment... -- only point 1 from this post matters, because point 2 was resolved by a helpful person below the post. But point 1 is still unresolved, and it looks bad.

2. Flutter runtime simply crashes on some mobile phones when loading the app. I've released an app on old SDK, and with every update of some minor thing + SDK I'm getting reports about new crashes from people who rated the app 5 starts on older SDKs, because it was working for them earlier. I've tried to report it: https://github.com/flutter/flutter/issues/43240 but my issue was grouped with some unrelated problem, and my questions were ignored.

3. I think the x86 codegen in Flutter is sometimes buggy. I've used a ZIP compressor/decompressor library written in pure Dart and it sometimes crashed in random location after using the library. I've tried to debug it but there was no pattern for the crash. The crash also was happening on the system level (SIGSEGV) instead of simply throwing an exception that would be catchable by Dart. When testing on the mobile phone, so when ARM codegen was used, I've observed no crashes and no problems when using the archive library.

4. Google AdMob has poor support for Flutter. The official AdMob lib doesn't support native ads, and is incompatible with widgets that draw an always-on-top layer, like Drawers or Action Buttons at the bottom right corner of the screen. It IS possible to finally work out the solution by using some thirdparty library which uses AdMob in a hacky way, but I would expect something better for one of the most crucial Google services like AdMob.

5. Until recently there was no support of Cupertino theme's i18n. I had to manually translate all texts of Cupertino theme to a different language (like 'copy', 'paste', etc).

I've released two apps in Flutter but I'm afraid to update them, because something always breaks after update.

Cordova and react native are going to disappoint you for the same reasons.

Everything sucks in its own sweet way :-)

With an expectation like this, I only can be pleasantly surprised :)

I worked on a react native project a year ago and hated it, mostly because of the story regarding interop with native code or SDKs. I imagine my experience would have been a lot better if the team didn’t “eject” from create-react-app-native, but I’m not sure how feasible it is to develop an app with ejecting.

If you want an idea of how good PWAs can get check out Pinafore:


Runs better than most native apps.

This is why one should only use SDK based tooling.

All software has bugs, and the less amount of layers to debug the better.

all software is buggy

On Android, that there hasn't been much love for C/C++ and the NDK is full of interesting pitfalls:

Oh your camera gives you NV21 frames, but the hardware VP8 encoder only accepts I420? Makes perfect sense.

Oh, we don't actually let you query what format the encoder expects until a later API than you're using. Just try them in a loop until one doesn't fail, makes perfect sense.

The camera was a party too, added a listener for Camera session events and the app crashed. Yay.

The Android camera issues you reference reached all the way up to the higher level Java APIs, at least back when I was doing Android development from 2012 until about a year ago. Dunno if it has gotten any better since then.

All of the MediaCodec APIs were quite powerful, but did nothing to "keep the easy things easy" or hide much of the lower level hardware details from your app.

This is kind of a theme in Android (or was... my experience is slightly out of date right now).

As mentioned by "McDev" in what is currently the top post on this thread it is a good idea to use time-tested third party libraries to do things that you'd kinda expect the OS to handle naively because the OS level APIs don't do a great job at abstracting any of the details away even for things that you'd think you shouldn't have to worry about, like basic image loading with caching and resizing. And that's just still images, never mind when you get into video de/compression.

Hopefully this is something the Android team is working on as they shift more effort toward Kotlin and Jetpack but I haven't had enough recent hands-on experience to know if this is better now.

It still is the same theme.

For Vulkan and real time audio they expect you to checkout GitHub repos and compile from scratch, instead of having the tooling as part of the NDK.

Likewise after 10 years they still expect everyone to manually write JNI bindings, instead of providing another productive way for language interop.

Well, glad to hear it's consistent at least :) Good news is we got a handle on all the little issues and now our code runs well on a wide selection of devices, but yeah, next time around I'd find a library that handles all the gory details.

I find image manipulation works pretty well, though I've only been doing Android dev for 2 years so maybe it's improved. Or I just haven't done anything 'fun' yet...

If you built it, they wont come. Without marketing, the odds of your customers discovering the app (amongst a sea of garbage) are insanely low. I tried a Tennis app in 2009 and even back then it was competing with hundreds of other apps, now its mist likely 10’s of thousands. Heart breaking.

Sometimes if you build it, they will come. I launched a music app in 2012 (student project), and over its lifetime (6 years), I had 95k downloads and 7 million sessions on the app.

Some apps have very low viral aspects like biz apps or Utils, also some standalone single player games. They will be at the bottom of a search result of 100s when first released. Quite demoralizing

Word of mouth marketing can be strong. For example I have purchased many apps because of a recommendation IRL, mostly music-focused (musicians love to talk about their kit). The point is to make something truly excellent, and if possible, conspicuous.

The years it took to realize how under-resourced the NDK team is, bothering to create my own NDK wrappers to work around the NDK bindings and forced JNI calls, manually dealing with dependencies across NDK projects.

In retrospect, it would have been easier to just rewrite the whole thing in Android Java.

Basically, how little Google cares for game related development workflows on Android.

It just took them 10 years to acknowledge this, go figure.


Don’t underestimate the value of build tools. Just because you know Xcode and Swift or Android Studio and Kotlin (or their antecedent languages) are you done. Finally having a senior dev who knows what he’s talking about has done more for me in the past two years than the previous 8 of reading blog posts and hacking. He’s shown me the real value of build scripts. Today even my personal iOS projects are dependent on a combination of Swift, Ruby, YAML, and Kotlin to build. It’s complicated to set up but I can prove that my code works.

Would you mind elaborating on how build scripts helped you (what problem did you solve?) and sharing learning resources?

>...dependent on a combination of Swift, Ruby, YAML, and Kotlin to build. It’s complicated to set up...

Can you elaborate on this? It just sounds like you have unnecessary complexity.

Can you explain more? I'd like to learn more about this.

Been doing Android development for 8+ years. The main thing to realize is that nobody actually knows what they're doing. You'll have a problem and spend hours and hours just searching for "the answer" but it's not out there. Everyone who has solved it has used their own hacks, and they're not going to be able to transfer the hack to you.

Once you realize this it's somewhat liberating. You focus on the bug/feature and not the method. One time I was trying to solve a particularly nasty layout-at-runtime problem and just realized I could write my own ViewGroup and lay it all out myself, pixel by pixel, faster than fighting RelativeLayout or whatever. And that code is more stable than something where I import some library that's not going to be maintained.

I regret it took me 5 years of mobile development (both platforms) to realize I really don’t like writing GUI code. I switched to backend and infrastructure work and I’ve been a lot happier since.

Example code is invariably dross from an architectural point of view.

Unit tests are still valuable in a mobile environment.

Most good apps are simple. Simplicity is not easy.

Some aspects of mobile development will become far easier over time (memory management on iOS) while some will remain in a baffling stasis (refactoring tools in Xcode). It’s impossible to predict which category an aspect belongs to ahead of time.

There are times to embrace the approach taken by a platform, and times to distance yourself from it.

Mobile as a platform will crush all before it and transform society, while most contemporary technological hopes will remain geek toys.

The remembering self can really help out the experiencing self; you can never learn too much about the past, present, and future of mobile programming.

That Apple and Google would move the goalposts so often, and with such vigor, that it'd result in classes of programmers who do nothing BUT support the mobile platform for development.

It has been a nightmare of keeping up with the majors, just to be able to enter their carefully curated arena.

Nowadays when I build an App, I do Linux/Mac/Windows first, and the iOS/Android release, next. Fortunately there is a vast industry out there for toolkits and frameworks for solving The Platform Problem™ which has been shoved down our throats by a ravenous corporate culture which is hell-bent on ensuring that they own the computing platforms of the future.

What, you don't look forward to WWDC to find out what syntax got arbitrarily changed with no explanation?

That JavaScript (and prior to that, Java) would work for mobile, one platform to rule them all.

Work = looks and feels native, good performance, good widget collection, development that doesn't fight the platform, and all those available not 10 years after the platform was introduced.

I can only agree with that. If you build a web app within a we browser you can use whatever payment method you want and the platforms don't take 20% for every transaction...

For android, get good at handling null everywhere in everything checking all the time now, or learn it the hard way later. You'll be spending lots of time tracking down "wait, how could that have ever possibly returned a null?"

Ditto async and observer and livedata type stuff. Never move data between things any way other than async. MVVM and all that, with caching repositories and stuff.

Architecture changes fast enough that you have to be careful not to waste time and effort supporting some ancient version and NIH writing your own implementations of stuff that's newly added in current versions. Yet if you try to ship using cool alpha quality features, that's a whole different headache. For extra fun you can end up with both problems at the same time in different parts of the app.

I got pretty good at Android development and made a few apps that don't have many downloads but I'm still proud of and wanted to share with my friends and family.

I regret that all of my friends and family have iPhones.

I develop for Android since 2011. Since 2016 I also do more iOS. I mostly regret not looking into new developments faster. Things like Kotlin and Architecture Components. They are great, so at least experiment a bit with them to see what all the fuzz is about. Try to keep up!

Also, I wish I realized that Google Play is giving you a lot of stats and data about your apps (store) performance these days, which in most cases can help pinpoint a issue with your reach/growth.

I also regret everything about Objective C ;)

I regret thinking that Xamarin was a good idea.

Amen. Management at a company I worked as were convinced that Xamarin was One True Path for mobile development. They were sold the idea that a Windows dev could instantly be productive in Xamarin without needing to understand the underlying platforms significantly.

To be clear, I do think Xamarin remains an interesting idea, but it's absolutely not the first thing I'd reach for when starting a x-platform mobile project.

> but it's absolutely not the first thing I'd reach for when starting a x-platform mobile project.

What would you go with now?

Ionic. HTML, JavaScript, and CSS work on (darn near) everything.

haha been there, should have left for a different company with our cto thinking xamarin was the best.

On iOS:

• Interface builder(especially Storyboards) is inferior to using UIKit straight from code

• Coordinator pattern, which lets you split logic and view controllers. https://www.hackingwithswift.com/articles/71/how-to-use-the-...

On Android: being paranoid about multithreading in all the wrong places before I stopped worrying and love the main thread.

Move actual work off thread whenever possible, but never try to integrate off threat memory access by hand using synchronized and friends, just enqueue your final result plumbing on the main looper.

Be paranoid about multithreading in the right places, particularly when you hand a callback to some black box. A callback that checks the thread it's running on to enqueue itself on main if necessary might become a familiar pattern. You might start to hate all callback methods that don't return void.

I can't really say I regret the path I've taken since had I not taken it, I wouldn't be able to form sound evaluations. I'd always sought out cross-platform development tools first on servers, then desktop, and mobile. Flutter/Dart comes closest at the moment but game engines might also work for certain apps. I'm glad I never bought into React-Native the worst of worlds. It's rare for an app to require native widgets and having to deal with two different sets and their idiosyncrasies isn't solving the problem.

I started with iOS in 2009. I wish I hadn't used Core Data, and made the decision to store lots of large binary blobs in it. Changing the schema became impossible, because the migration process often crashed or ran out of disk space in production. That, coupled with lots of Core Data crashes that persist (pun intended) to this day. It may have been easier to just use SQLite directly.

My decision to use NSThread for worker threads wasn't optimal either, but there weren't many async options in 2009 (Remember ASIHTTPRequest?)

That mobile web apps aka PWAs are a perfect fit for classical data-driven applications. The return on investment for 2 native apps vs. a PWA is far...

You're not allowed to use full PWA capabilities on iOS though right?


One can always build a hybrid app from a pwa...

I should've started a year later when ARC was introduced (I started learning between 2011 - 2013).

Learning iOS dev with reference counting as a memory management system was really painful. My programming skill wasn't up to speed yet to "just" learn a new language. I only knew some university Java at the time. And while I did write impressive projects with it, I wasn't strong enough in an algorithmic sense.

Learning a framework and learning memory management, and kind of needing to deal with pointers but not really proved to be too much.

When ARC was introduced it was a breeze.

Now, when I read this whole comment, nowadays I'd think: this is such nonsense. Memory management should not be a barrier to learn iOS dev. But when you're in that weird space of that you kind of know how to program (5000+ lines code) but you really need to get into it, and it doesn't feel natural yet. Then, yea, it does matter a lot.

A few years later I learned C and had no issues learning pointers or memory management. To be fair, I didn't need to use any frameworks with C.

The whole damn thing. I’m self taught web developer, server management, backend stuff. I love a Rest over HTTP API. X Code and all the sims do not jive with my brain. Swift helped a bit. But only ever able to build a bouncing ball game. The process of launching on an app store alone seems insane. I started by FTP and Perl then PHP. I pay people to write code these days.

React Native isn’t nearly as good as the hype suggests, and the pain only gets worse as your project grows.

Why do you say that? What are some of the issues?

The tooling is just unstable in general in my experience. You never know when things will get into a bad state and you have to kill everything and clear your caches and restart. And then in my experience styles don't actually behave the same way on iOS and Android. They also continue to make breaking changes so you always have to be worried about not only your own code but your dependencies handling that appropriately. The debugger itself is also prone to crashing and requiring full restarts at inconvenient times. Overall, I feel like the amount of random bullshit and platform specific workarounds I have to do makes it so I'm not really saving time VS having 2 native apps and I'm less confident about the overall quality of my software. There's also A LOT of valuable things in the native SDKs that no quality wrapper exists for, so you're missing out on a lot of productivity benefits of the underlying platforms.

If you think you will ever be cross platform, do yourself a favor and write as much of the business logic as you can in C++ or C. The platform-specific piece should be small and “just enough to make the platform happy”. Do everything else portably from the start.

To get into mobile sooner. I was tired of the web and burned out needed something different. I’m getting way more work and enjoying myself a lot more. I hope to have a long career programming so maybe I’ll change platforms again one day.

MVC, the way it’s implemented in UIKit, leads to code that is very difficult to test, mixes business logic and view layout and navigation, and leads to massive view controllers. You have to be very careful to avoid it.

When doing custom UI animation code that isn’t native, expect 2-10x more development, testing and polish, and still won’t achieve it perfectly.

I built an iOS game using Sprite Kit and had to hack together support for multiple screen sizes later which was kind of a pain. Likewise they make you provide an app icon of like 25 different sizes. Have not done standard UI work yet but unless you use a “reactive” set of layouts I can only imagine the pain.

Yeah if you plan the development around different screen sizes in beginning would be best, otherwise architectural changes will prob be needed unless like you side to hack it

I wish I had realised that Android app development ecosystem (the dev tools, API, documentation, gradle, dependency management etc) is a shit show and is going to remain a shit show and I should have moved to backend early in my career. Now companies are very reluctant about it.

reluctant about what? backend developers?

The xcodebuild command line tool is insanely powerful. The one provided by vanilla Xcode is awful.

I invested lot of years on Android because it is, promoted as open source etc ... but currently it is just their advertising platform, complete control of it developer (removing developer accounts, blocking apps and devices ) and full monopoly !!

Go cross platform as soon as you can! Most folks preaching against it don't have the practical experience. If you're not writing games and writing a non graphic intensive app, it's the way to go.

That you need a singleton pattern to ease the gps refresh problem. Totally rewrite the program before submit to Apple store.

How hard it would be to Port.


On the iOS side, I regret not knowing how horrible Xcode is and how horrible Apple's documentation is. On the Android side, I regret not realizing that no matter what kind of slick new well documented APIs Google releases we will all be writing code for Android 4.4 for the rest of our lives. Also, I wish I knew mobile developers are some of the lowest paid developers other than game industry peons.

> Also, I wish I knew mobile developers are some of the lowest paid developers other than game industry peons. I wish I can tell you you were wrong here but I only have anecdotal evidence. Maybe you’re stuck in a company that’s taking advantage of you with a low salary?

I have recently looked at surveys in my country and mobile developers are one of the most paid programmers out there, especially the ones experienced with Swift. What does cause the low pay in your country? Logically the sector is ever expanding and there is always demand for hires with any experience.

> I wish I knew mobile developers are some of the lowest paid developers other than game industry peons.

Everything is relative of course, but can you back up your claim with some numbers?

Where do you live? What salaries and compensation packages are you seeing?


Well, ok, I guess it's not that grim. Still, it's a pretty crappy job.

> The specific technologies that developers use also impact salary. This year, the technologies most associated with high salary include Go, Scala, Redis, and React.

Surprised me seeing Scala in there, thought it was basically dead now. My last experience with seeing it in a codebase and using (or trying to use) SBT, I was kind of hoping it was.

If you had your choice, would you do something else? Like being in finance or becoming a dentist?

as a mobile dev at the FANG companies, were paid the same as other engineers. in fact, some are paid more because of the smaller talent pool

this applies to web developers as well. too many devs on both web and mobile, so salaries are lower then rest of IT technologies. usually a web/mobile dev needs to know a lot more to make it on the same par, at which point you can argue is a full stack one anyway.

Applications are open for YC Summer 2020

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact