Could you elaborate on whats messy with these SDKs?
Could you elaborate on whats messy with these SDKs?
Also, patterns like KVO are still found from time to time as a last resort in frameworks, while being famously unsafe and still rely on the obj-c runtime.
For android basically everything should be rewritten from scratch. Last time i managed a team of android developpers, we basically came to the conclusion that doing regular mvc while supporting a good market share meant recoding our own controller base classes and screen transitionning apis.
A lot of time is spent just on this treadmill of porting previously working things to modified APIs. To make it worse, you have to manage a 4-way compatibility matrix between Swift versions, XCode versions, iOS versions, and macOS versions, where only very specific combinations work.
The most notable one looks like in the String API [1]. There are a few other minor ones that most projects won't hit, like in the dictionary/set API [2]. A few of these are also slightly more breaking than it initially seems because they've added temporary compatibility workarounds marked as deprecated in Swift 4 to avoid breaking as much working Swift 3 code, but these will go away for Swift 5, so you do still have to port anyway (just not immediately).
[1] https://github.com/apple/swift-evolution/blob/master/proposa...
[2] https://github.com/apple/swift-evolution/blob/master/proposa...
I disagree with most of this. Laying out views was a mess for a while but auto layout is easy to get right once you understand the fundamentals (especially when used in storyboards). Springs and struts is old pre-autolayout tech which shouldn't be used. CALayer is the lower level object that UIView is based on. Not sure what the complaint is here (they're mostly unrelated to autolayout/springs and struts).
As for CoreData it's a pretty simple way to manage your data. When originally introduced to iOS it was a mess but I've used it extensively in the last few years, first through a higher level framework (MagicRecord I think?) and now directly and it providing you exercise some care around threading it performs very well, especially for something simple like offline data storage.
Ever had to deal with Core Data migration on an app that needs to evolve throughout the year ? Migration is a mess, and so is concurrency. My personal conclusion after having used Core Data on a pro application for 4 years, is that most of the time i really don't need a database and so i'm back to file-based backups for my app's data. Works well, no magic, and no performance or threading issue.
Yes. I've found AutoLayout to be acceptable in this case, provided you're not doing something awful.
If you have sixteen views on a cell and their locations all depend upon each other, it's going to take a long time to solve those constraints. But if you can break up the cell, say into four subviews with four elements inside them, it's likely to be faster (no guarantees, though)
Unfortunately, i had to write my own constraint system and practice with it a lot to use AutoLayout with high performance where i was confident i was not introducing significant re-layout performance problems.
Yes, even on a 4S.
https://www.youtube.com/watch?v=g6yz5oX5iWc
FWIW, if you like and good at it, more power to you.
https://en.wikipedia.org/wiki/Delegation_pattern
So you start some sequence (like a new UIViewController) and interact with it via callback events instead of having a single (blocking) thread of execution that waits for the view controller call to return like a function. This makes it virtually impossible to deterministically model flow control. Note that since Android copied many metaphors from iOS, it also inherited these complexities in things like its Activity class.
I agree that Core Data probably needs to go away (at least its iCloud integration) and be replaced by Firebase or PouchDB etc.
KVO was a great missed opportunity because it's not clear who is watching a value. I think the pattern itself has merit from a functional programming perspective (after all this is how Excel works).
I generally avoid native mobile development now for these reasons among many, not to mention cross-platform issues. We likely need web metaphors running above native code, writing plugs where necessary (like Cordova or React Native). These are generally quite painful to use though, so I don't see many solutions materializing for at least several more years.
Why on earth would you have a single blocking thread on a UI app?
The tradeoff was that it took pages of boilerplate to make even the simplest app, and Apple got made fun of incessantly for it. So they largely fixed that with OS X's message passing metaphors, but unfortunately due to bloat and a lot of other reasons, the boilerplate issue came back, and now we're also stuck with untraceable program flow.
To answer the original question - I have worked on both blocking and nonblocking code, and unfortunately nonblocking code doesn't scale. It eventually becomes too complex to follow the flow. It's like comparing a coroutine to a state machine. My personal feeling is that we're in a kind of nonblocking bubble right now and that the callback style that pretty much all frameworks use today is not going to be the way it's done in the future. I don't know what will replace it, but it will likely be something more like Redux/Elm/Clojure and declarative GUI syntax like how the web used to work.
It's one reason they had to rely on compile-time codegen to implement the swift4 equivalent.
- APIs return non-descriptive error codes like -16405. Some of them aren't documented. And even the ones that are are not found clearly. Different codes are documented in different files. If you don't know where to look, you won't find it. Java-style descriptive error names like InvalidFrameRateException are sorely missing. iOS should either adopt exceptions or at least string error codes like INVALID_FRAME_RATE, not -16405.
Sometimes, there's no error code at all. I'm trying to record a video, using a AVCaptureMovieFileOutput, which is supposed to save to a file, and it doesn't. There's no error code, no exception, no log message telling me what went wrong and how to fix it. I spent a day or two trying various possibilities but nothing worked.
- Common abstractions like a photo gallery class aren't missing. It took me a month to write my own, because there are a lot of cases to deal with: swiping left and right, pinching to zoom, double-tapping to zoom, keeping the photo centered while zooming, taking care not to zoom the whitespace, keeping the photo gallery in sync with the Photos app (the user might delete a photo either in your app or in the Photos app, and you need to sync in both directions), and so on. Even now my gallery class doesn't support swipe down to close, which the Photos app supports, as I was told yesterday. That's what happens when you make people reimplement things — you'll get an inconsistent UX.
Forget a photo gallery class. Even a zoomable photo view is missing. It took me days of messing with UIScrollView to figure this out, until I found the ray wenderlich tutorial.
- Some APIs come in both sync and async versions, while others, like permissions, come only in an async version, though a sync version would be easier. Even the async APIs are inconsistent -- some invoke your callback on the main thread (UIKit APIs), some invoke it on the same thread you invoked it on, and some in a random thread (AVCapture). I filed a radar asking for consistency (maybe all async APIs can take a queue to invoke the callback on) but Apple closed it as WontFix.
Unfortunately, Swift doesn't have async/await, so dealing with the async APIs is a pain, and for some reason, this is not even a priority in Swift 5. It's being put off for years.
- Permissions are a pain to deal with, especially the common case that your app can't run without some permissions, like Camera and Photos for a camera app. I had to deal with the following cases:
+ You should take care to request a permission only after the previous one has been approved or denied by the user. Otherwise, you'll get a prompt for Camera, and before you respond, it disappears and is replaced by a prompt for Photos. And before you can respond, it disappears and is replaced by Location. When you respond to it, the Camera prompt re-appears, but again disappears and is replaced by Photos. This is a bad UX, caused by iOS not queueing multiple permission requests internally and asking the user for one only after the previous request was responded to.
+ You should ask for location before camera, because a GPS fix can take time.
+ You should take care to obtain permission before accessing the camera, otherwise the camera will vend frames consisting of black pixels, which you might accidentally save to the Photos app.
+ iOS distinguishes between a permission being denied (by the user) and restricted (by an admin or parent). My app would crash in the latter case, because the camera device is not found. But not in the former, because the camera exists but vends black frames.
+ If the user changes permissions of your app while it's running, Apple says that iOS will kill your app and restart it so that you don't have to deal with permission changing dynamically. Except when it doesn't, which goes back to the denied vs restricted case above.
In summary, you waste months of your time working around insufficiently-documented iOS issues, or debugging things, or reimplementing common things in every app.
I conclude that iOS is a poorly-designed platform from the developer point of view. Maybe other platforms are worse, I don't know, but iOS certainly is far from what it could have been. Ideally, you should implement only what makes your app unique.