Flutter for MacOS
My first case study for building apps for MacOS was to use Apple's built-in capability of running iOS apps natively on Macs with Apple Silicon (see https://www.wafrat.com/flutter-ios-app-for-macos/). This time, since I want to use features that may not be available on iOS such as a proper File Picker, I want to make compile my Flutter app specifically for MacOS.
Google Sign-In
Starting from https://pub.dev/packages/google_sign_in#platform-integration, I am told to refer to the integration steps for iOS and MacOS: https://pub.dev/packages/google_sign_in_ios#macos-integration.
So I set up [my_project]/macos/Runner/Info.plist
the same was as I set up [my_project]/ios/Runner/Info.plist
. I also add this additional key-value as instructed:
<key>keychain-access-groups</key>
<array>
<string>$(AppIdentifierPrefix)com.google.GIDSignIn</string>
</array>
When I run the app and try to sign in, I can enter my credentials and accept what permissions I grant the app upon signing-in, but as soon as I click "Next", the Google sign-in page disappears, but my app does not receive any Google credential. There is also no error in the console.
Printing out errors
In the documentation, they show how listen for errors. However I could not find this API in google_sign_in 6. So I had to migrate to the 7, which is the latest major version.
googleSignIn.authenticationEvents.listen((e) {
print('event');
print(e);
}).onError((e) {
print('error');
print(e);
});
Now I can remove the configuration and add them back one by one to make sure they are truly necessary.
GIDClientID
This time, upon clicking the Sign-In button, the Google Sign-In page does not pop up. Instead I get this message.
flutter: Sign in failed: PlatformException(google_sign_in, No active configuration. Make sure GIDClientID is set in Info.plist., NSInvalidArgumentException, null)
Good, let's add that back to [my_project]/macos/Runner/Info.plist
.
CFBundleURLSchemes
flutter: Sign in failed: PlatformException(google_sign_in, Your app is missing support for the following URL schemes: com.googleusercontent.apps.[redacted], NSInvalidArgumentException, null)
After adding this step, the Google Sign-In page does pop up correctly and lets me enter my credentials. Upon clicking "Continue" to finish the sign-in process, my app throws this error:
flutter: Sign in failed: PlatformException(org.openid.appauth.general: -5, Connection error making token request to 'https://oauth2.googleapis.com/token': The operation couldn’t be completed. Operation not permitted., {NSLocalizedDescription: Connection error making token request to 'https://oauth2.googleapis.com/token': The operation couldn’t be completed. Operation not permitted., NSUnderlyingError: {code: 1, domain: NSPOSIXErrorDomain, localizedDescription: The operation couldn’t be completed. Operation not permitted, userInfo: {_NSURLErrorFailingURLSessionTaskErrorKey: LocalDataTask <FBF44A34-B484-4D53-8E25-F065580CA914>.<1>, _kCFStreamErrorDomainKey: 1, _kCFStreamErrorCodeKey: 1, _NSURLErrorRelatedURLSessionTaskErrorKey: [LocalDataTask <FBF44A34-B484-4D53-8E25-F065580CA914>.<1>], _NSURLErrorNWPathKey: [Unsupported type: NWConcrete_nw_path]}}}, null)
Outgoing Network Connections (not documented!)
This is actually not documented in the google_sign_in documentation on pub.dev. When I asked Gemini about it, it revealed that I should enable outgoing network connections in XCode.


Incoming Connections?
When I wrote this post, I noticed that Incoming Connections (Server) was already checked, and I was not sure why. So I disabled it, and now I know:
✓ Built build/macos/Build/Products/Debug/elysium_mobile_client.app
2025-09-08 09:42:29.794 [app_name] Running with merged UI and platform thread. Experimental.
flutter: Could not start Dart VM service HTTP server:
SocketException: Failed to create server socket (OS Error: Operation not permitted, errno = 1), address = 127.0.0.1, port = 0
#0 _NativeSocket.bind (dart:io-patch/socket_patch.dart:1220:7)
<asynchronous suspension>
#1 _RawServerSocket.bind.<anonymous closure> (dart:io-patch/socket_patch.dart:2166:12)
<asynchronous suspension>
#2 _ServerSocket.bind.<anonymous closure> (dart:io-patch/socket_patch.dart:2521:12)
<asynchronous suspension>
#3 _HttpServer.bind.<anonymous closure> (dart:_http/http_impl.dart:3506:24)
<asynchronous suspension>
#4 Server.startup.startServer (dart:vmservice_io/vmservice_server.dart:317:23)
<asynchronous suspension>
#5 Server.startup (dart:vmservice_io/vmservice_server.dart:339:11)
<asynchronous suspension>
#6 _toggleWebServer (dart:vmservice_io:229:5)
<asynchronous suspension>
2025-09-08 09:42:30.134 [app_name] The operation couldn’t be completed. (OSStatus error 13.)
```
Flutter needs to connect to it to provide debugging information.
keychain-access-groups entitlement
After restoring the Incoming Connections Capability, I am getting the next error:
flutter: Sign in failed: GoogleSignInException(code GoogleSignInExceptionCode.providerConfigurationError, keychain error, {NSLocalizedDescription: keychain error})
This one looks familiar. It is the one that https://pub.dev/packages/google_sign_in_ios#macos-integration mentioned:

However, the error persisted even after adding this key/value to Info.plist
. So I read about it a bit more on https://docs.flutter.dev/platform-integration/macos/building#entitlements-and-the-app-sandbox. It turns out entitlements are written in another file: macos/Runner/DebugProfile.entitlements
.

Gemini suggested to add the Capability using the XCode UI itself. That would have prevented my mistake.

Weird XCode compilation setting
After adding the Keychain Sharing Capability, my app wouldn't launch anymore. When I checked in XCode, I saw this new error:

I had to Enable Development Signing for my app to run again.
Google People API (not documented!)
At some point in the process, another error I got from google_sign_in was that I should enable the Google People API at https://console.cloud.google.com/apis/library/people.googleapis.com. So I did, but what is puzzling is, I have never had this error on iOS.
Success
After setting all of this up, my Flutter app compile for MacOS and I can successfully sign into my Google Account!
Publishing to TestFlight
Reference docs:
+ xcodebuild -exportArchive -exportOptionsPlist ...
2025-09-08 14:30:08.535 xcodebuild[7313:3471315] [MT] IDEDistribution: Command line name "app-store" is deprecated. Use "app-store-connect" instead.
error: exportArchive No signing certificate "Mac Installer Distribution" found
error: exportArchive No profiles for '[package name]' were found
** EXPORT FAILED **
[14:30:32]: Exit status: 70
Validating

The value of the CFBundleDocumentTypes key in the Info.plist must be an array of dictionaries, with each dictionary containing at least the CFBundleTypeName key. (ID: 76cfdd64-fce6-4823-88c3-5791ae6d9895)
That's becaeuse I accidentally added an empty one by clicking around the XCode UI earlier. Removing this:
<key>CFBundleDocumentTypes</key>
<array>
<dict/>
</array>
Publishing to TestFlight
After the few tweaks to Info.plist, XCode successfully validates. So I try to Distribute to TestFlight, and that steps successfully completes too. As soon as that step completes, I head over App Store Connect, and I do see that a build for macOS has appeared in my app's TestFlight tab!
At first the tab is gray, but after a few minutes, the UI renders and shows that its status is Processing.
Fastlane
Now that I've successfully distributed a macOS built to TestFlight, I am hoping that the Mac Installer Distribution error I encountered with Fastlane has been resolved. Let's try to publish another build again with Fastlane.
I increment my app version in pubspec.yaml, then try again.
And sure enough, it worked!
[15:47:48]: Successfully exported and compressed dSYM file
[15:47:48]: Successfully exported the .app file:
[15:47:48]: ./[app name].app
[15:47:48]: Generated plist file with the following values:
[15:47:48]: ▸ -----------------------------------------
[15:47:48]: ▸ {
[15:47:48]: ▸ "method": "app-store"
[15:47:48]: ▸ }
[15:47:48]: ▸ -----------------------------------------
...
[15:49:41]: Successfully exported and signed the pkg file:
[15:49:41]: ----------------------------------
[15:49:41]: --- Step: upload_to_testflight ---
[15:49:41]: ----------------------------------
[15:49:41]: Login to App Store Connect ([account name])
[15:49:43]: Login successful
[15:49:44]: Ready to upload new build to TestFlight (App: [app id])...
[15:49:44]: Fetching password for transporter from environment variable named `FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD`
[15:49:45]: Going to upload updated app to App Store Connect
[15:49:45]: This might take a few minutes. Please don't interrupt the script.
[15:52:53]: ------------------------------------------------------------------------------------------------------------------
[15:52:53]: --- Successfully uploaded package to App Store Connect. It might take a few minutes until it's visible online. ---
[15:52:53]: ------------------------------------------------------------------------------------------------------------------
[15:52:53]: Successfully uploaded the new binary to App Store Connect
[15:52:55]: Waiting for processing on... app_id: [...], app_version: 0.9.54, build_version: 54, platform: MAC_OS
[15:52:55]: Read more information on why this build isn't showing up yet - https://github.com/fastlane/fastlane/issues/14997
[15:52:55]: Waiting for the build to show up in the build list - this may take a few minutes (check your email for processing issues if this continues)
[15:53:25]: Waiting for the build to show up in the build list - this may take a few minutes (check your email for processing issues if this continues)
[15:53:55]: Waiting for the build to show up in the build list - this may take a few minutes (check your email for processing issues if this continues)
[15:54:26]: Waiting for the build to show up in the build list - this may take a few minutes (check your email for processing issues if this continues)
[15:55:02]: Waiting for App Store Connect to finish processing the new build (0.9.54 - 54) for MAC_OS
[15:55:33]: Waiting for App Store Connect to finish processing the new build (0.9.54 - 54) for MAC_OS
[15:56:04]: Waiting for App Store Connect to finish processing the new build (0.9.54 - 54) for MAC_OS
[15:56:35]: Waiting for App Store Connect to finish processing the new build (0.9.54 - 54) for MAC_OS
[15:57:05]: Waiting for App Store Connect to finish processing the new build (0.9.54 - 54) for MAC_OS
[15:57:37]: Waiting for App Store Connect to finish processing the new build (0.9.54 - 54) for MAC_OS
[15:58:07]: Successfully finished processing the build 0.9.54 - 54 for MAC_OS
[15:58:07]: Using App Store Connect's default for notifying external testers (which is true) - set `notify_external_testers` for full control
[15:58:07]: Distributing new build to testers: 0.9.54 - 54
[15:58:08]: Export compliance has been set to 'false'. Need to wait for build to finishing processing again...
[15:58:08]: Set 'ITSAppUsesNonExemptEncryption' in the 'Info.plist' to skip this step and speed up the submission
[15:58:09]: Successfully distributed build to Internal testers 🚀
+-------------------------------------------+
| fastlane summary |
+------+----------------------+-------------+
| Step | Action | Time (in s) |
+------+----------------------+-------------+
| 1 | default_platform | 0 |
| 2 | build_app | 675 |
| 3 | upload_to_testflight | 507 |
+------+----------------------+-------------+
[15:58:09]: fastlane.tools just saved you 20 minutes! 🎉