9 years of Apple text editor solo dev
papereditor.app
papereditor.app
1) A connection; I feel like I noticed something just for those who care 2) Assurance the product is well cared for 3) A feeling that the dev understands me
This stuff is gold for a product. I am thinking of Procreate when I think of the king of this sort of thing. That app is just so ridiculously clever. I don't know how they managed to take the plethora of UI that other illustration apps have and squeeze it down into ~6 menu items. Somehow it works beautifully and there are so many subtle touches and hidden workflow gestures just waiting to be discovered. It's usable out of the box, and the more you use it the more you naturally learn how to use it more efficiently.
Shouldn't that be pretty easy to implement, too? Just a button that prevents rotation...
(Un)fortunately in many other cases it doesn't work like that. People use a certain app to book train tickets even its UI sucks hard and it asks 100 permissions unnecessarily, because the only alternative is get it over the counter in person.
It's worth questioning why this is, as often as you can. We have a wallet app / payment system on most mobile devices that is card agnostic and gets better interfaces. Meanwhile, other services have to make do until a big player like Amazon or Ticketmaster comes along, consolidates the industry and starts charging high rents.
Prime example I stumbled upon recently: In Apple Music, you can press+hold an album or song to pop open an action menu. I use this a lot for adding songs to the queue. There's an item to add it next in the queue, and another to add it last in queue. Usually if I want it somewhere specific in the queue, I'd just add it next and then move the song where I wanted it, but if I'm adding an album partway through the queue, that means you'll be dragging a bunch of tracks manually. So I thought, "it'd be nice if I could just drag things exactly where I want in the queue and drop it there." And then I figured I'd actually try it. If you press and hold a song/album and yank it from its place, it stays under your thumb. You can then either operate with another finger to open up the queue, or hold your thumb over it to pop it open, and then just drop it exactly where you want in the queue.
Not the first time I've come across something like this, but it's the kind of thing I only find on Apple platforms, particularly with their own apps. As much as I liked Google Play Music, you couldn't do it there, and I just checked Spotify and it doesn't let you do that either.
To reveal the filter field, you must select the "View" menu, and "Show Filter Field". Worse each time you relaunch Music, this field is again hidden, and you have to select the menu item again.
people discover these touches in the breech, when they need to move on for some reason or other, and all that's familiar is lost. in the words of Joni Mitchell, "you don't know what you've got till it's gone"
I made the move to Swift when it came out. However, there are many times I miss Obj-C and many of the advantages you mentioned. I often wonder what Obj-C would look like today if Apple had put the time and effort into it instead of Swift.
I was not aware of your app. I just downloaded it on my Mac and iPhone. It is really nice! I like the little things you have done, like the hints on the menu bars for using the Option key, and the hint disappearing when you do. I am going to continue to use it.
Thanks for sharing your experiences. Best of luck!
It would largely look like Swift, since the goals of Swift (and most modern languages), safety and expressiveness, are fundamentally incompatible with C languages. There's really no point to basing a language on Obj-C if you're not keeping 100% compatibility, so they didn't.
You could've had Obj-C without the C for example, ADTs (enums), strong nullability enforcement and a nicer syntax while reusing most of the Obj-C core and retaining the compile speed, rock solid / fast debugging, function calls as data (selectors), easy mock creation and so on.
The systems programming capabilities is lost on %99.9 actual usage of swift. The swift project should've been split into two different projects IMO, where they modernized Obj-C into a successor language without making the C++ choices they did and created SwiftRust where the %0.1 that want system programming and nondeterministic multithreading capabilities can go do so. Apple second system effect-ed themselves hardcore with the Swift project, and it shows everywhere.
Safe system programming is one of the key design goals from Swift.
And it's funny you mention systems programming, since Swift is still relatively bad at that compared to C++ or Rust, and most of its improvements in that area are recent and ongoing. It'll be another release or two before the memory movement features are fully in place and the language allows full control over ownership (without unsafe heroics at least).
It’s not a coincidence that macOS/iOS has long had a disproportionally large quantity of high quality indieware. Capable framework + minimal headaches = polished apps that an individual or small group can sustainably support, even within less profitable niches and without VC funding.
Cross-platform applications have their place, but sometimes I like having features that I can get in one place and nowhere else. Let them both exist and quit griping about it.
And what is the result? Everyone complains that Qt is too hard to use, and so it has utterly lost the cross-platform war to Electron, and meanwhile the devs who want the platform-native functionality (like the OP of the article) use the OS-native toolchains instead.
There's no silver bullet here.
The way Qt Widgets is for practical purposes usable only with C++ or Python is one such thorn, as is its use of custom types like QString. Both increase friction significantly as many devs aren’t able to use their preferred language and can’t use the language primitives they’re familiar with. Qt Widgets apps also require a good deal extra elbowgrease to make feel good on all supported platforms due to oddities in widget layout and drawing, and to my knowledge use of newer features (like blurred “vibrant” (macOS) or “mica” (Windows) window backgrounds requires dropping down to native code.
For QML, devs are stuck with JavaScript (which while functional, isn’t everybody’s cup of tea) and face some of the same issues that web/electron devs do with needing to pull in third party frameworks (like MauiKit[0]) to have a usable widget set.
Distribution is a problem across the board in Qt with tooling being a less than great state. It’s a very common issue to see crashes in Qt apps as a result of some incantation being missing.
In short Qt has the right idea, but I believe it’s held back by many of its technical and design decisions. I’d like to see a project that’s like it, but built in a modern language with good C interop so high quality efficient bindings can be easily generated, and has a bigger focus on good DX.
[0]: https://mauikit.org
QML is actually pretty amazing. I've been building my block editor[2] view entirely in QML while the model is in C++. This separation of logic and presentation works great. And yes, there are some crashes sometimes (that I find quite easy to debug thanks to the built-in debugger), but take for example a similar app that's built with Rust and Dart[3], in my testing there were still memory leaks that caused my computer to hang. It's better to know you have a bug than for it to be hidden from you.
I agree with parent commenter, saying these cross-platform frameworks will end up supporting the least common denominator set of features. But I found with external open source libraries, the community is catching up very fast. For example, you want the awesome translucency macOS apps have for your Qt app? Here you go[4]. Many such cases. It's also pretty straightforward to add your own custom OS-dependent code, especially so, if someone already open sourced his approach. I recently wanted to move the traffic light buttons on macOS for my app, but couldn't figure the Objective-C code for that. I ended up looking at either Tauri or Electron source code and found my answer.
[1] https://github.com/woboq/qmetaobject-rs
What happened with using the best tool for the job?
So what if C++ and Python are the only bindings.
Which is that platonic toolkit I do not know of that is easy to distribute, productive, fast and available in any language?
Developer experience is extremely important but it’s consistently something that’s swept under the rug with Qt, much to its detriment. Devs at large would rather be limited to a single platform or make huge tradeoffs in efficiency than live with bad DX.
This fundamentally doesn’t work for UI/UX. You have to pick a paradigm and implementation details at some point and the high level UX design of Windows UI dejure and Mac are just different, in ways that cannot be factored out of a framework without leaky abstractions.
Your choices are: the Qt/Tk/Swing approach write once, a solid if dated UX that is themeable but not truly native anywhere, the web app (or its QML/Flutter/FX equiv), wxwidgets etal which sort of tried to be native everywhere last century and looks and works that way, or at least two parallel independent native UI implementations which is a gargantuan more effort.
Or go whole hog with FLTK or your own custom thing. a11y? WTF is that?
“ Instead they typically take a least common denominator approach, limiting apps written with them to only the most common basic features.”
I wouldn’t call wxwidgets basic, but it is a mess. It can’t be any other way. If it could someone would have made it in the last 30 years.
Just because you use Cocoa/AppKit rather than drawing on a canvas does not magically make your app feel like a Mac app.
Literally 100s of side projects have started down this path. People eventually learn you can’t abstract everything away, at least not the labor intensive part.
I agree that not every app must be cross-platform. Text editors are a good example. The economics may or may not be more difficult. Yes the audience is smaller but the cost may be lower as well and you may have a competitive edge over cross-platform apps.
The problem with starting a single platform app is that you have to decide very early on that you're not going to need any collaboration/sharing features (unless the app is built on top of some cross-platform protocol or file format) and that you're not going to serve multi-platform users any time soon. This is a big decision with far reaching consequences.
I think there's a risk for developers (and tech bloggers) to become so enamoured with the fine details of their platform of choice that they lose touch with the priorities of the user community.
I beg to differ. Many industries (Graphic design, many engineering disciplines and game development) have a defacto platform for this exact reason
Trying to build for multiple platforms is a lot of overhead, not to mention UI paradigms don't always map one-to-one. Even building for both Mac and iOS (versus just iOS, for instance), for me, can be challenging since there are enough to differences between the two platforms in terms of UX that I have to take extra care to nail both experiences faithfully.
There’s also the whole third party dependency mess referenced in an earlier post, which is unavoidable with both — anything more involved than “hello world” is going to have a mile long list due to how barebones the frameworks themselves are.
Many B2B apps are built as plain web apps that run in the web browser and connect to a backend (CRUD apps). That's because business customers care less about the presentation, and more about the value that the software might deliver. If it saves them time or money - they will buy it no matter what the UX is. And many of them even prefer a tab in the browser, since they do their work in the browser anyway.
With B2C users often expect a more polished experience. More often than not they pay for a nicer, more polished thing, rather than for something that solves a particular pain point. Of course, the app should be useful, but that's table stakes. The deciding factor often becomes the UX. Thus in B2C, the client technology plays a bigger role. Depending on how many competitors offer a native UX, the users might not even consider you if they see that the app is not lightning-fast or has some weird, custom UI that looks off.
React Native has some native UI elements, but then many other things such as the navigation stack are reimplemented from scratch which results in a UX that appears to be similar, yet may work in weird ways that differ from native behavior. Plus React Native is pretty slow in my experience, and like any cross-platform thing has a ton of other weird edge cases and annoyances.
I have not used Flutter, but from my understanding, they have reimplemented the whole UI stack from scratch, and draw everything on a low-level graphical canvas. This means that it is even less native than React Native. They emulate/copy the native UI, but it is not the same. Not to mention that they have to do a ton of work to keep up with the latest changes in Android and iOS. Feel free to correct me.
For B2B, React Native, Flutter, or even Web/Electron are perfectly fine. For some less competitive B2C categories as well. For super competitive ones native is almost always a requirement.
The promise of fantastic cross-platform apps still hasn't borne out. We've been promised this since Java, yet converged on shipping Chrome with a webapp.
This could be done despite nobody I know working this way. This used to be normal when x-windows was thriving.
Also, it turns out to be much faster than comparable native apps (performance benchmarks available on the website).
EDIT: Fixed.
Contrast with a lot of the web frontend ecosystem, where stuff might go stale within a few months. And the overall pervasive feeling of jank that comes when you're building UIs. (Though, I presume this goes away once you internalize browser layout engines better.)
For my two Mac apps, I use very few third party deps. They're simply not needed! They serve small, discrete purposes and could be replaced by bespoke code at a moment's notice. This is how software should be built! We've just forgotten about this because the browser ships with so little in terms of UI components.
It went ABI around Swift 5 or so.
I took a huge leap of faith, in 2014, and started using Swift, exclusively. It's turned out OK.
I'm not quite as positive about SwiftUI, though. I think it will work out, but it has a huge amount of catching up to do, if it is to replace UIKit/AppKit.
I'd be quite interested in Rich Siegel's take (the guy behind BBEdit). He's been at it, a while, as well.
It's like you go through a SwiftUI tutorial placing @Published and @ObservedObject everywhere, and then once you're writing the app you realize what you need is Combine except you haven't learned that yet
Looking inside the BBEdit app, I see some Swift in BBEdit.app/Contents/Frameworks/CandiedYams.framework, which appears to be a third-party framework (CFBundleIdentifier org.darkrainfall.candied-yams), but not much else.
I've been using BBEdit for about thirty years. It's been through many changes. I suspect that he's pretty conservative.
Apple's stubborn and bizarrely proud insistence on not providing the full solution here is very annoying.
Those seem like very basic features that a UI framework needs to get right.
I’m having a lot of fun with it at the moment. If you stay within the bounds of how they encourage you to build the apps, you can just go go go and with very little work release a fast, stable, native app across all their platforms.
The APIs for NSTableView and NSCollectionView, in contrast, were always very responsive and performant when used in the default way.
All of this greatly reduced my trust in SwiftUI. Seems like they did not have performance in mind in the core design decisions of the framework, and only tested it on small data sizes.
Maybe things have improved since then.
I kind of wish that SwiftUI was a clean break in some ways and did not depend on UIKit and avoid all the abstraction leak issues that have been arising as a result. I know that would never happen in practicality although.
For me this is an invaluable lesson to learn. A pet peeve of mine are tutorials or guides which consist of a list of external packages and libraries to add before writing a line of code.
This write up is excellent though, some of the gripes I have with the Apple eco system the OP has turned into a 'learning' experience in a positive way. Really nice.
likewise, 80% of the tutorial is preamble to prepare for the 20% you care about.
just don't.
And it's still the most useful guide to setting up Qt because it's the only first-page result that mentions Berkeley.
> do you really have no access to SDK code as a reference?
You get headers but no source. While Darwin is in theory open source, UIKit, et. al. are not.
> I got to that assembly code part and just sat there and re-read it again and again.
If you're referring to the screenshot, Xcode dumps you into disassembly in cases where the stack is not in your code. 0 -[MoTextView endFloatingCursor] is the author's code. The remainder is UIKit. Also, most of the line items are _prefixed which indicates a private method upon whose existence (much less implementation) is not reliable. As the author mentions, the stack on the left is usually enough to diagnose problems.
It's also one more thing that makes me fight using Swift; all of the name-mangling and opaque to the Objective C runtime additions make this problem even harder.
And then curse Apple when the internals change and your app breaks?
Apple ships betas, so there is plenty of time to see if stuff breaks with the latest OS.
Is that really the case with Apple dev? I'm genuinely curious.
I wound up extremely tired of the continuous moving target of web dev - especially in terms of x-browser compat, and very intentionally avoided it as much as possible professionally. The likes of WinForms, WPF (the Silverlight subset is still the best UI framework that I've used), GTK, and QT were significantly less frustrating - dare I say enjoyable.
A question out of curiosity. What are your thoughts on re-writing in Swift?
If it were me, I am sure my tech-fingers would itch for a rewrite, but my business hands would slap those thoughts away.
I probably would have to do it at some point if Apple decides to completely deprioritize it.
For now, Objective-C even has some benefits. It's more low-level and more hackable. And I think some older APIs are not even available in Swift.
Also - how did you do the visuals in the "Gnarly Bits" section that split the page/components out into verticals? That is such an amazing way to display the internals of a thing like a page.
If these elements could be packaged into a blog theme for whatever blog hosting platforms are popular these days I bet you'd get a bunch of people to purchase. Nice work!
The component split is done by hand in Figma with regular screenshots and cropping. I also used a plugin for skewing.
IMO customizing scrollers is almost always a disservice to users.
It's a single form-over-function thing that I could not resist not to add. :)
I've expanded it by default on bigger screens now. :)
Just look at the Microsoft equivalent: yes, C# is good and all, but the hardcore Windows apps are still using (lightly-skinned) VC++ APIs - after almost 25 years since they started flogging .NET.
Swift is for the new rubes, bootcamp graduates and so on.
C# is a totally different story.
Interesting. Can you share more details?
C# was created as a Java competitor. Although it had great C interoperability, the underlying .NET Framework was still a VM-based runtime with a garbage collector and all the disadvantages that brings. You can probably find various articles (https://longhorn.ms/the-reset/ is one) discussing attempts to adopt C#/.NET code for Windows Longhorn, which ultimately had to be walked back completely. .NET wasn't purpose-built for writing OS components or working deep inside existing Windows code.
Apple learned from this and other examples. The Swift team actively works with teams at Apple deep in native code to make sure they can handle their use cases without performance penalties, and with minimal ergonomic issues.
The difference is really about what the stated goals of the language were/are.
Sure, Apple cares less about backward compatibility, but still, it's unlikely Objective-C is going anywhere, under the hood.
That's a mult-year project in its very early stages, yet we're already almost 10 years into Swift (more than 10 years of Swift internally to Apple).
> All new code is in Swift.
False.
> All new frameworks are Swift-only.
False.
It has already shipped, replacing parts of Foundation in the 2023 OS versions. It continues to grow, and it's a rewrite, so it certainly proves your assertion wrong.
My other points were a bit hyperbolic. Feel free the replace "all" with "the vast majority of". Apple obviously still writes Obj-C in their existing Obj-C frameworks, and doesn't arbitrarily rewrite into Swift, but their internal barriers to use Swift are now almost entirely gone. And I can't think of an entirely new framework that wasn't Swift-only recently.
Which assertion was wrong? I was paraphrasing from the project page itself:
"It is in its early stages with many features still to be implemented." https://github.com/apple/swift-foundation
Your original assertion that Apple wasn't rewriting anything.
I have no idea what you're talking about. I made no such assertion.
Perhaps you're confusing me and "toyg"?
My point, as always, is the truth. You said two false things, which you subsequently admitted were hyperbole. Truth is valuable in itself, and more important than "points", i.e., arguments or motives.
If I were to make a point, though, it's that Objective-C still has a very long life ahead of it, and its complete replacement, if that ever occurs, will be an arduous process, given the amount of extant Objective-C code in the operating systems and first-party apps (not to mention third-party apps). It's not just Objective-C either: C++ is also used quite a bit in the OS. Think of WebKit, for example.
By the way, we could be hired, for the right compensation. Nonetheless, companies almost never try to recruit me, but they still whine about how "hard" it is to find ObjC developers. They're not even looking.
Besides, experienced engineers can learn a new programming language. Do you think that every engineer Apple hired before 2014 had Objective-C experience?
Sonoma is 13% Swift (up from 11% in Ventura), 53% Obj-C (down from 55% in Ventura). The priority actually appears to be eating away from the C/C++ parts of the codebase (currently 33%, down from 42% just two releases ago).
https://blog.timac.org/2023/1128-state-of-appkit-catalyst-sw...
That was a bit rude and unnecessary.
Why do you say that? Do you have experience backing up that estimate?
I would think if the C/C++ developers didn't have their head up their **[1] that could be a standard out of the box feature. There isn't any reason a program couldn't spit to stderr, 'seg_fault: file boots.c, line 1043'
In C++ I'm dubious you couldn't throw an exception instead of dumping.
[1] Got rid of frame pointers because they were sure that would make their dog slow C++ compilers run faster. Voice over. But it didn't make them faster. It made programs impossible to profile.
I definitely wouldn’t call Swift a 10x improvement in efficiency, and I like coding in Swift. I do advent of code in it each year, but spend a fair amount of time just fighting with the compiler–after all these years, it still emits strange or just flat out incorrect diagnostics.
We need more apps like this in every category.
That's a huge difference, but I believe it's because Swift is meant to be somewhat cross-platform, right?
This seems to be premature optimization. The author forced himself to learn archaic Objective C for a completely unnecessary reason, and now is stuck with that design choice despite not having any benefits.
Some benefits:
1) Most Swift code written in 2015 when the author was starting won't even compile today, because the language has changed in non-compatible ways. Whereas Objective-C code written in 2015, 2005, and possibly even 1995 will usually still compile and run. The author mentioned low maintenance costs as a goal.
2) Swift compile times are still vastly slower than Objective-C.
3) The Swift tooling is still buggy, including the compiler, and especially the debugger (the author wrote an entire section about debugging).
If I started a new app today, I'd use Swift -- it's mature enough. But in 2015 and for a long time after, it wasn't really a good option unless you wanted to be on the bleeding edge (and you were willing to bleed).
Compile times will always be slower than Objective-C, but the compiled code _can_ be faster, with effort. And maybe someone will eventually break down and write a Swift-centric debugger.
Of course, the pressure to rewrite would grow with every year as Apple continues deprioritizing Objective-C, but that's a problem for future me. :)
So all the NS_SWIFT_UNAVAILABLE APIs are still easily bypassable in Swift?
It's easy, now, to say that it was a poor choice/premature optimization/unnecessary/whatever. But, presumably, the author is unable to tell the future. At the time when the decision was made, there were benefits that the author deemed necessary (smaller distributable among other benefits).
Actually, building on stable abstraction is a pretty nice benefit when your focus is on the product.
Swift is quite nice, IMO, but has also changed quite a bit since 2015 and using it would likely have lead to a bunch of work to keep up.
I'd hesitate to put it that way.
Shipping software is always full of compromise, and we often have to stay away from the "bleeding edge," when we want to actually ship full-featured products.
I suspect that almost all the AAA apps are still ObjC.
I still use UIKit/AppKit for my work. I simply can't get the results that I need from SwiftUI.
The word that comes to mind after reading that post is “intentionality.” Many deliberate decisions, including for hard tradeoffs like this one. To me, that speaks to the importance of vision and judgment over the apparent correctness of individual choices.
Swift is lighter on the eyes, but it still uses the same APIs when paired with UIKit/AppKit.
SwiftUI is a different thing though. It's like React for UIKit/AppKit and has a different API.
I've been (very slowly) dabbling around writing a Game Boy emulator in Swift and, surprisingly, some of the biggest difficulties I've had have been actually getting stuff on-screen, rather than the emulation itself. Turning an array of bytes into pixels on-screen, timers accurate enough to run my main loop at 59.97Hz, window behaviour etc.
I know all this stuff exists and isn't even that hard, but actually finding what I need has proven quite difficult. I found that Google searches for NSWhatever tended to return results for UIWhatever, and there are far fewer StackOverflow threads due to a lot of this stuff being from the early 2000s.
Apple's documentation for their newest stuff is infamously barebones, but I've also found it difficult for the very old stuff too -- much of it hasn't been updated for Swift, so I've been at the mercy of Xcode autocomplete to find the new names for various constants, etc. Good Mac development is starting to feel like a lost art.
Can't recommend anything specific, to be honest. I've been piecing together information from old Apple docs, StackOverflow, API header files, and a bunch of really weird blogs. A lot of trial and error as well.
I think your best bet is ChatGPT. It has seen every possible use-case of Apple APIs from GitHub so it should know a lot. I've gotten some good tips from it for very specific things that did not exist on the web.
Whilst I'm just a web developer, I've had times, even using third party libraries that aren't particularly well documented, where ChatGPT seems to have a shockingly good grasp of the library and seems to understand it better than the documentation does.
It's a lifesaver honestly.
> By the way, I also use categories to shorten long framework methods. The underscore at the end helps to avoid clashes with public or private methods that Apple might decide to add in the future.
I think you already know what will happen if Apple adds a method (public or private) called text to NSTextField or stringValue to UITextField in the future ;)
I don't know, what will happen?
I agree with his approach - I remember writing Objective-C back in 2015/2016. At the time, Swift had just launched but it was nowhere near ready for production. So I had to learn Objective-C/UIKit/etc. As frustrating as it could be at time, I overall have pretty fond memories of it, and I got really good at it.
I've lost the skills since then but hope that Swift has matured enough to be suitable.
Ignoring popover presentations in UIKit, there’s also a new TipKit framework in iOS 17, but it’s Swift-only.
https://developer.apple.com/documentation/TipKit
The author has done a great job while remaining in Obj-C. I’m really curious how long they can avoid Swift, keep the native experience, and offer new features in the platforms.
I think so far when Apple added new features to existing components, they've always made dual APIs. Only some completely new things are Swift-exclusive.
That said, as the pile of those exclusive things gets bigger, it would be harder and harder to stay in Objective-C.
Sounds like you rely on Categories a lot. Check out Extensions in Swift. [1]
There are some limitations (e.g., Swift enums lose a lot of their power if they're needed in Obj-C) but overall the interop is great. I don't remember anything in UIKit that couldn't be done with Swift. And if you're dealing with unicode text, doing things in Swift may make your life much easier.
[1] https://docs.swift.org/swift-book/documentation/the-swift-pr...
I'll definitely give it a try at some point.
Thanks!
I think, technically, you could emulate NSPopover with the latter. I will need to test it.
Feel free to clarify, if I've misunderstood your comment.
I wanted to avoid Objective C, largely because I liked the safety of Swift (optionals, if let, guard let, etc) to make it less likely that I'd introduce crashes.
The funny thing I found was that I ended up needing to know how to at least read Objective C code anyway, because like you say, the docs use a lot of it. StackOverflow had a lot of it too. So I had to get good at translating between the two.
Unlike the web dev world I was used to, there are way fewer Swift/ObjC devs out there, and the answers are fewer and less up-to-date.
Paper appears to have a more traditional split between text mode and preview mode, and you can't properly edit the formatting in preview mode (e.g., you cannot turn a heading back into normal text from preview mode).
I'm sure it's a pain to implement, but it's the one really killer feature of Typora that I can't live without.
You can format from the Preview mode, by the way. You need to use the shortcuts for that or click inside the Format menu. If you put your caret on the line of the heading, then press Command+1/2/3 depending on the level of the heading it will convert the line back to normal text.
I'm just one person, but for me, this was the feature that made me switch to a minimalist text editor for writing.
Otherwise, why not stick with Emacs? Plain text with light syntax highlighting is something Emacs already does fine, it's relatively distraction free, it has keyboard shortcuts I've already memorized forward and backwards.... The biggest downside is that I have to pop over to another window to get proper syntax rendering and to be 100% sure it's parsing the way I expect.
Anyway, just my two cents. I could totally understand it not being worth the effort to implement, but when it works, it's really nice.
I did not, however, invest the time to make it expandable. I thought that people anyway don't use the scroll bar that much, and for quick navigation there is the table of contents on the left.
I'll see if I can make it more accessible!
It's hard to do when every popular platform seems intent on making it unusable.
This would give the appearance of your current 2px scrollbar, but it'd be usable, and would visually expand out to show its grabbable area on hover:
html::-webkit-scrollbar {
width: 8px;
}
html::-webkit-scrollbar-track {
background-color: transparent
}
html::-webkit-scrollbar-thumb {
background: #d73f00;
background-clip: padding-box;
border-left: 6px solid transparent;
}
html::-webkit-scrollbar-thumb:hover {
border: 0;
}
(The key to it is the background-clip property, that lets you use the border to control where the background is drawn.)You could also do exactly-this but without the :hover state, and it'd effectively just increase the grabbable-area of the thumb without any visual change to your current style. I like changing the visible width as a form of feedback though. :D
Seems to work.
Thank you!
Not trying to take anything away from the author: the app and this post look great. But consider doing more writing like this and breaking them out into a dedicated, non-SEO feed. I'd subscribe to that in a heartbeat.
The current RSS feed is not useful for humans. I'm not into SEO, so maybe RSS feeds are taken into account. You can publish multiple feeds, though.
I've indeed forgotten about the RSS feed. That post was created in 2021, but I keep stuff up to date even for SEO content, so the update time is 2024. That said, those posts are purely for keywords - they have no value other than to get occasional clicks from Google, and to spread the word about Paper.
I'll think about separating the feeds.
1. The blog is flooded with SEO oriented posts https://papereditor.app/blog This vs That, Top this, Top that
2. In the App Store a whole bunch of other text editors are mentioned in the app description text in order to be included in the results when people search for other text editors.
I'ts just shady and unnecessary if you trully believe in your app.
1. What's wrong with SEO? People discover the app from Google. Some of them even become paid customers. If people discover and purchase what they need - what's the harm?
2. That does not affect the App Store search results. If it would have - everyone would be doing it. App Store allows a lot of text in the description, so I thought I would fill it with something useful. I've also ordered the names from shorter ones to longer ones so it looks like a mountain. Aesthetic details everywhere. :)
2. I've seen plenty of apps doing the same trick in the App Store. But if it doesn't affect the search indexing why even bother putting up a long list of apps that could hurt your business.
Nothing but respect for the work that you do and the app you've created.
2. I don't see why it would hurt. If people read the description and see the familiar name of the app that they use or have used, they will associate Paper with that app. It's just a list of writing apps - Paper is a writing app. I am trying to make a connection in their heads.
Thanks - I love a good discussion!
Please, I concur with the other people who suggested this
[0]https://developer.apple.com/library/archive/documentation/Us...
https://developer.apple.com/library/archive/documentation/Us...
Sadly, not enough to live off it in Europe.
But it's slowly growing, so maybe one day. :)
I have a copy of IA Writer that I've somehow never used, so maybe I'll buy this to add to the pile.
There's occasional spam, but the barrier of having an Apple device to spam is enough to not make it a problem.
It's remarkable that even today, with millions of apps, you can still find paying customers through the App Store even if you are a nobody.
What is your flow for accommodating new OS changes (some being quite dramatic)? Do you make list of broken things and new opportunities, then devise a complete solution? Or do you address them incrementally?
Great write up. Thank you.
Still on TextKit 1. I am thinking of migrating to 2, but I still have downloads on older Macs, so I want to wait. Supporting both 1 and 2 in parallel would be a nightmare.
To be honest, I have not experienced a lot of dramatic updates. Apple has a good track record of keeping things backward compatible. The issues that I find on the new betas, I fix before the OSes are released in the Fall.
I have one small gripe in that on my browser (chrome-windows11) the scroll bar is imperceptibly small, so I can't easily scrub through by grabbing it with the mouse. Other than that this is awesome.
Sorry, I'll try to make it more accessible.
Would it be possible to have a basic mode where one makes a one-time payment and has the option to hid all nagging about "Pro" features?
Enjoyed even the transparency on pricing thinking, but one price that doesn't seem to have been experimented with is allowing a one time purchase that is not an in-app purchase.
In-app purchases make your app unavailable to company employees where the company manages the Apple device using MDM and purchases software using e.g. Apple Business Manager or the older volume purchasing. The $99 option should also exist as a standalone retail version so a company can buy the app for employees.
For small app makers: you might be surprised that a company-managed Mac with a company managed AppleID cannot use in-app purchases. Apple has no way for a company to do IAP for an employee, and in fact the employee cannot do it themselves either. For such users, you must either (a) allow retail app purchase, or (b) have an out-of-band subscription purchase and management, like Microsoft M365 or Adobe Creative Suite.
Whether you do it out of band or as a one time retail purchase, if you do track logins, you should support the simple "Login with" or "Continue with" buttons for Microsoft to hit the 85% of small businesses with identities on that platform, but also Apple and Google. These buttons are easier to add than devs might think. You don't need "SSO" to let most companies log in with company IDs.
I've always avoided non-App Store distribution to keep things simpler. It's a nightmare to manage many different licensing schemes.
Now I don't have to have any backend. Everything is done via the built-in, robust App Store mechanism that just works.
I hope Apple will figure something out in the future. And I think they will since they want to increase their "Services" revenue as hardware sales decline. Making stuff easier for business customers seems like a low-hanging fruit.
So you'd have 2 apps listed:
- Paper (Lifetime) ... $99
- Paper ... Get
Companies can buy employees the first one because it has a price.
> Everything is done via the built-in, robust App Store mechanism that just works.
Good call, and so true.
Hm. I feel like having 2 apps could confuse some users. But maybe it's worth it. ¯\_(ツ)_/¯
This has been going on a long time, once upon a time it was used for Free with Ads versus Paid: https://www.kodeco.com/2404-how-to-create-both-a-paid-and-li...
See also this discussion, mentioning family sharing though instead of mentioning corporate purchasing: https://apple.stackexchange.com/questions/243954/which-purch...
I'm not at work so I can't readily pull up a list of the apps we can and do buy employees thanks to having a paid version available, but there are quite a few, and they win out over more popular apps that have only IAP.
I searched for "Pro" and found a sort-of example:
- Korg Module (Get+IAP): https://apps.apple.com/us/app/korg-module/id1048875111
- Korg Module Pro ($39+IAP): https://apps.apple.com/us/app/korg-module-pro/id932191687
(These are not productivity apps for employees like companies are looking for, just an example done at both price points.)
Anyway, if you had a $99 paid version, our company would buy copies for employees.
I think the regular, unsophisticated user might still be confused. I already envision questions like: "Should I buy a lifetime license in the free version or the paid pro app?". There are also additional hurdles like, for example, reviews being divided between 2 separate apps. I don't know, maybe it's worth it, but I am hesitant. I want to keep the whole experience of Paper simple, and this just adds complexity. I would prefer to wait for Apple to solve this at some point in the future.
Paper does support family sharing, by the way.
I will ping you on LinkedIn if and when I will make a separate app.
So my worries about confusing users are baseless.
I can put a link in the description of the main app and businesses can purchase the app from the link. Sounds amazing!
Here is the link:
Huh, that sounds contrary to what people usually tout as a benefit of native. You always hear about framework churn and cross-platform problems when it comes to JavaScript. Maybe that’s not so true anymore?
I use React and it had exactly one significant major change (class components -> functions & hooks) since 10 years ago when I started out with the beta release.
Windows went through 4 different "recommended" GUI frameworks and many more major API changes during that time.
Update: jokes aside, this is a great read. Adding vim keybindings would violate the principles of this project.
Yearly subs are 50$. Lifetime is 100$. That video shows the number of Pro users, not subscribers.
It expands in the app as you hover over it. Probably needs a similar thing for the website.
Or I just need to give up and revert it to the standard one. :)
Yes please.
The visuals and attention to detail reminded me of Bvckup (https://bvckup2.com).
Downloaded the app to check the "smooth caret" somebody mentioned, started typing and got interrupted after 3 words by a popup telling me to check out PRO features. Oh well. Next, a OS popup about notifications... no thanks. I don't expect any notifications from a text editor. Or at least give me a minute to check it out on my own.
No thanks...
I'll think about delaying that popup. :)
I should delay asking about notifications as well. It's for the support chat that I mentioned in the article. If I write back in that chat, I fire a local notification. Makes sense more sense to ask for that permission only when the user has written something to the chat.
Many many years ago, I used to run a web hosting company. One of the first things I did was I built one of those little chat widgets that let me chat directly with visitors on my website. This was around the year 2000 and before I had ever heard of liveperson which was somewhat new at the time. That single feature did more for my business than anything I did. Because I could talk directly with customers (and potential customers), and because I was the sole decision maker for the business, I was able to say yes to ridiculously obscure requests for features that were easy to implement but very valuable to just one specific customer. My hosting business never grew into a large company but it did support me through college and for a while afterwards.
I was a really powerful sales and support tool.
But in this case I feel that paper was crafted with a strong vision and care. So you could say that you can _tell_ this was made with love.
This has been the distinguishing feature, as against all the other feature-full applications. Its success has spawned copy-cat's in this and other domains.
The solo dev can avoid following the herd. Developer groups, esp. groups with investors, require mutually-acceptable justifications that reduce to, well, joining the herd.
So as a solo dev, amplify this advantage, and ask: what do people really want, that they can't get from the herd?
(Esp. in an age thundering with AI mash-up's)