Originally, the title was “uncover the mystery of macOS development”, but think about it, with my current understanding of macOS development, or remove the word “uncover” 😂

This is not a systematic article, more like an essay. Think back to the past 1.6 years of macOS development and pick something interesting. If you want to dig macOS after watching it (if so), you’ll be disappointed; Let’s read it by anecdote.

Note: Technically, it’s called “macOS development,” since Apple rebranded the Mac operating system as macOS last year; Still, apple’s computers are still named after macs, like the MacBookPro, so Mac development makes sense; Plus, it feels weird to start with a lowercase letter as the title of the article, because this article mixes “Mac development” with “macOS Development.”

—– long start cordon; Please detour —–

0) Mac is the eldest son by stepmother

Mac is said to be the eldest son, because Apple is a computer started. Although later iPod, iPhone popularity, but the blood of the eldest son is pure; And iOS is built on macOS. There are a lot of stories here, so read books or articles like Steve Jobs.

Unfortunately, with the iPhone as a cash cow, macs fell by the wayside, and macOS didn’t update until they had to. Even when it’s updated, it’s like squeezing toothpaste.

Where is the Mac left out? Lots of them.

For example, EVERY week I get an email from Apple to developers telling me how active the App is that week. And every time I get an email, it says something like this:

Because I don’t have an iOS App, only a macOS App; In Apple’s view, macOS apps are not apps. ! So, the data here is empty…

The list goes on and on.

1) Mac is a small market

How small is it?

Starting with hardware, here’s how q4 shipments compare:

equipment shipments revenue
Mac 5.37 million 7.2 billion dollars
iPhone 78.3 million 54.3 billion dollars

Whether shipments, or revenue, are a fraction.

Take a look at the number of apps:

According to AppShopper data, the number of macOS apps is less than 30,000, less than 1% of iOS apps. Yes, “one percent,” a fraction of a percent.

Of course, the focus here is on apps that make it to the MAS (Mac App Store), but there are a lot of apps outside of MAS. But, two orders of magnitude difference, no run.

Now let’s talk about the operating system ratio:

MacOS accounted for just 6.12% of Windows users and 6.7% of Windows users, according to MarketShare.

The macOS version, while much more fragmented than Windows, is also less fragmented than iOS:

See here, do you feel a little cold heart, feel the Mac is so poor have you…

But the Mac is slowly gaining traction and recognition. For example, most of the computers in modern urban dramas in China are Macs. Apple just announced 100 million active Mac users worldwide.

2) Swift or Objective-C

I developed applications (Klib, iPic, iPic Mover, iPaste, iTimer, iHosts), all based on Swift; However, even if you plan to be Swift based, a basic understanding of Objective-C is recommended. Objective-c is, after all, the language apple has always used for development, and the vast majority of documentation, tutorials, are based on Objective-C.

It could easily be adapted to Swift, or called by Swift, but it’s like: you have an English dictionary and you can theoretically read articles in English because you can look up words you don’t understand. But you know, that’s not realistic, because you can’t look up every word, right?

So:

  • If you already know objective-C, you can develop Mac applications directly in Objective-C. Should I learn Swift? Depending on your mood, I don’t offer advice;
  • If you don’t have objective-C basics, I suggest you learn Objective-C basics first, then learn Swift, and develop on Swift.

3) Mac documentation and tutorials

The official documents mainly include:

  • MacOS Developer Center
  • API Reference
  • Programming Guide
    • Table View Programming Guide for Mac
  • WWDC video over the years
  • Guides and Sample Code
    • Some sample projects are provided here. For example, if you want to learn a control in action, search here.

In fact, since we’re generally “programming for Google,” we tend to search first and don’t need to keep track of these urls. However, if you want to learn something systematically and deeply, you can start with the official documentation directly.

A word of warning, though, about Apple’s development documentation: it’s not great. If we use this sentence: “How can I know so much but still have a bad life?”

It’s: “Why am I looking at all the Mac docs and I still can’t develop a Mac app?”

The documentation is more of an introduction to a specific topic, and if you want to get a systematic introduction to macOS, it’s best to get a good book and practice on your own. Thanks to the popularity of the iPhone, iOS books are piling up. What about macOS books? Ha ha.

I myself got started on macOS development by reading Cocoa Programming for Mac OS X, which was pretty much the only Swift based macOS development tutorial I could find in 2015. The other one is Swift Development with Cocoa. It can’t be compared with this one.

I don’t read many other macOS books and don’t have much to recommend. If you think of a good book, feel free to let me know in the comments.

4) macOS data structure and persistence

First of all, although it is macOS development, many of the basic things are actually common, such as JSON format, MySQL database, etc.

Also, macOS doesn’t have as many unique things as iOS, like TouchBar; There are more generic, or parallel sets.

Use plist files to store data:

  • Only simple data structures are supported by default; This method is only suitable for saving small amounts of data, such as On/Off options in preferences
  • You can useUserDefaultsManage the default PList file. Note: Sandbox mode and normal mode default plist file location is different
  • It can be used on the command linedefaultsCommand to manage data in plist files
  • You can use Xcode to open plist files for management

Serialized storage:

  • For custom types, adaptNSSecureCodingAfter the agreement can be usedNSKeyedArchiverconvertDataformat
  • In turn, it can be stored in normal files or plist files

Core Data:

  • Core Data is essentially an encapsulation of how Data is accessed
  • For simple Data structures, using Core Data introduces additional complexity and is not cost-effective. For complex applications, Core Data can significantly reduce the amount of code
  • On the persistence side, Core Data provides object-relational mapping (ORM) functionality that allows Data to be stored in SQLite database files or restored to memory without writing any SQL statements

CloudKit:

  • In storage, CloudKit is essentially like a relational database in the cloud
  • In addition to storage, CloudKit is more useful for synchronizing data across multiple devices and between macOS and iOS. For example, Notes and other applications of the system store and synchronize data through CloudKit. A notification mechanism minimizes the amount of data that needs to be synchronized
  • Furthermore, cloudKit-based sharing is provided

Note: There are many ways to store data persistently, depending on specific requirements; Here are just a few common ways.

5) macOS interface development

When we talk about macOS development, by default, we usually mean developing “interface and interactive applications that run on macOS.” Interface and interaction are at the heart of it.

We also often hear about Cocoa. What is Cocoa? Quoting from Cocoa Programming for OS X:

Cocoa is your application’s interface to the window server to receive events and draw to the screen. At the same time it has access to the Unix layer where it can make lower level calls.

That is, Cocoa is an intermediate link that connects your applications to the windowing system, but also directly to the underlying system.

Interface development, is a bottomless pit; This can be a simple single-window application, or a more complex application such as Pages or iMovie.

For starters, menu-bar programs are a good place to start. You can bypass complex topics like Windows and controls for a while and create applications that solve real problems. For example, the iPic main interaction is located in the menu bar:

The Status Bar App tutorial was written in April 2016, but some of it may be out of date now, such as Swift 2.2. But the whole thing can be referenced.

Back to interface development. First, understand the overall App lifecycle. Especially when the App starts, what it does, in what order, and what its dependencies are.

Then, the actual work, is to fix the interface layout, and familiar with the use of a control, such as NSButton, NSTextField, NSTableView and so on. Recommended learning steps:

  • Play casually first, can let the control run; Some controls are so complex that you can’t run without feeling frustrated
  • If there is a Programming Guide available, read it carefully
  • If there is an official sample program, study it and become familiar with its proper use
  • Go through the API Reference to understand all the possibilities and limitations of the control
  • Solve their own practical problems, really use

My general development steps:

  • Figure out the data structure
  • Pile of UI
  • Complete business logic

6) Decoupling of macOS design patterns

As the program gets more complex, the code gets more and more intertwined. For further development and maintenance, is a very headache.

How to avoid this situation? One idea: decoupling.

In the abstract, it is to take a complex thing and break it up into individual modules, and then make those patterns fit together organically in some way.

In what ways? Along these lines, LET me outline some concepts.

The MVC pattern (Model – View – Controller)

  • This pattern is used a lot in interface development, such as XXViewController, which you often see in the Controller section
  • In short, it separates interface from logic. Interface parts, such as layout, style, etc. Usually, the most code is in the Controller. Between View and Controller, data is passed by reference and binding, that is, data is displayed in the interface, and user-generated data is read from the interface

Delegate

  • There are two ways to think about agents. Taking NSWindowDelegate as an example, it can be understood that Window itself has rich customizability, and the program can selectively implement some functions and features
  • Another perspective is that, as with NSWindowDelegate, the response of the Window itself to an event (such as a Window about to close) is either unknown or business specific. Windows can’t do this on its own, so it has to delegate to its own “agent”. For example, when a window is about to close, the program prompts the user to save unsaved data

Callback

  • For non-real-time operations, Callback callbacks can be used to decouple the wait between the caller and the performer
  • For example, when an application downloads an image from the Internet, it may take 1ms or 2 seconds. It can’t wait around. So the program tells the downloaded module: ‘I’m busy with something else, let me know when you’ve downloaded it.’ How? This is done through the Callback mechanism
  • Concepts associated with it, such as code blocks

Notification

  • The answer to “if… Such logic is more suitable for the notification mechanism
  • Notifications are not only pushed from the network, but also from within the program
  • For example, after the user completes the account upgrade in the interface of preference setting, the notification of account type change will be sent in the program. The main window of the program was previously registered to listen for this notification, allowing you to adjust the interface in real time based on the account type

7) Release macOS apps

Programs that you’ve worked hard to develop are usually ones that you want more people to use. If I can make a little money, so much the better.

7.0) macOS application signature

For simple programs, you can copy them to run on another computer, but it’s best to sign them. In particular, applications that use some Apple features, such as CloudKit, must be signed.

How do I sign my name? The premise is to pay. That is, you have to pay Apple a $99 annual poll tax to become an Apple developer and sign your app.

7.1) MAS and sandbox mode

Applications submitted on MAS must run in sandbox mode.

The sandbox mode has many limitations, such as no access to any of the user’s files by default, some interfaces are unavailable, and so on. The macOS sandbox is much looser than the iOS sandbox. Take file access as an example. Applications can apply for access to specific directories such as Downloads. To whom? Apple, not users. Once through (though not easily), you can access the directory directly without user authorization.

In fact, the sandbox mode does limit the application space, and some applications (such as screen translation and screenshot tools) simply cannot be posted, or they only work with an additional “Accessibility”. Apple is said to have stopped releasing apps that require such access.

7.2) MAS Payment method

Apple supports a variety of in-app purchases, and the easiest way to charge for apps is to make them pay to download. In this way, there is no need to distinguish between the free version and the advanced version, no need to do any functional restrictions, the code is simple. Apple’s system guarantees that apps downloaded with the Apple ID will only work on computers logged in with the Apple ID. For example, if you buy a paid app and copy it directly to a friend’s computer, it won’t work.

However, there are limitations: users can’t experience all the features of the product before they pay, making it difficult to decide whether to pay. To address this limitation, some apps offer a full-featured trial version on the product website that only runs for a short period of time (say, seven days). In this way, users can experience all the features and decide whether to buy or not.

One step further is the model of free + in-app purchase. Users can download the app for free, but only basic features are available in the app, requiring in-app purchase to use advanced features. This way, I can maximize user acquisition and charge for it at the right time, which is what all of my apps are doing, and I believe will be the trend for some time to come.

For internal purchase, divided into one-time purchase and subscription system. One-off purchases are easy to understand; The subscription system can be monthly, quarterly, annual and other cycles. For subscription system, and divided into automatic renewal and manual renewal. Currently, Apple has a hard time vetting subscriptions, especially those that automatically renew them.

In addition, there are consumable in-app purchases, which are more common in games, such as spending money to buy equipment or recharge your account.

For the development of in-purchase, or more tedious, such as to deal with the display, purchase, user purchase after refund, restore, subscription renewal, subscription not renewed due to expiration and so on logic. Fortunately, I’ve wrapped IAPHelper so it’s easy to handle this logic (the following code is the purchase part); Open source, Pod can be integrated, has been applied in my products for many years, you can rest assured to use.

 IAP.purchaseProduct(productIdentifier, handler: { (productIdentifier, error) in
    if let identifier = productIdentifier {
        // The product of 'productIdentifier' purchased.

    } else if let error = error as? NSError {
      if error.code == SKError.Code.paymentCancelled.rawValue {
        // User cancelled

      } else {
        // Some error happened}}})Copy the code

7.3) Imperfect MAS

Apple takes 30 percent of the money an app receives from its users.

MAS’s restrictions, along with a hefty plucking fee, have led to the removal of many well-known macOS apps, such as Sketch and Dash.

However, there are still many things to do to launch outside of MAS, such as download, pay, refund, activation code, etc. For small programs, it’s cumbersome and not cost-effective. And, after all, MAS brings in some natural traffic.

One more thing to note if you publish outside of MAS: the.app is essentially a folder. If you need to send it over the Internet (as an attachment to an email, for example), it’s best to compress it, or even make.dmg files. I use create-dmg, which is very convenient and the resulting style is simple and elegant.

For the above reasons, currently all my applications are released on MAS, but not outside MAS.

The tail

There are so many other topics for macOS development, such as Storyboard, binding, animation, concurrency, Undo, Pasteboard, Drag & Drop, localization, unit testing, etc., that I can’t cover them all in this article. And, write up also tired, after all, must have a complete grasp of these points, it is possible to write out. Dig a hole for now and fill it up later.

Interested in macOS development? Welcome to leave a message.


Original text: “free development” public number