Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

macOS support #471

Draft
wants to merge 12 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions .metadata
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled.

version:
revision: 32fb2f948e9b1a2d1b876ebee3558be7f51b457f
channel: stable

project_type: plugin

# Tracks metadata for the flutter migrate command
migration:
platforms:
- platform: root
create_revision: 32fb2f948e9b1a2d1b876ebee3558be7f51b457f
base_revision: 32fb2f948e9b1a2d1b876ebee3558be7f51b457f
- platform: android
create_revision: 32fb2f948e9b1a2d1b876ebee3558be7f51b457f
base_revision: 32fb2f948e9b1a2d1b876ebee3558be7f51b457f
- platform: ios
create_revision: 32fb2f948e9b1a2d1b876ebee3558be7f51b457f
base_revision: 32fb2f948e9b1a2d1b876ebee3558be7f51b457f
- platform: macos
create_revision: 32fb2f948e9b1a2d1b876ebee3558be7f51b457f
base_revision: 32fb2f948e9b1a2d1b876ebee3558be7f51b457f

# User provided section

# List of Local paths (relative to this file) that should be
# ignored by the migrate tool.
#
# Files that are not part of the templates will be ignored by default.
unmanaged_files:
- 'lib/main.dart'
- 'ios/Runner.xcodeproj/project.pbxproj'
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

<!-- To benefit from the current changelog reader in CI/CD, please follow the changelog format from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). -->

## [4.4.0](https://github.com/builttoroam/device_calendar/releases/tag/4.4.0)

- Added macOS 10.15+ (Beta) as a supported platform (tested only on Intel based Macs)

## [4.2.1](https://github.com/builttoroam/device_calendar/releases/tag/4.2.1)

- Updated multiple underlying dependencies
Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,3 +108,9 @@ For iOS 10+ support, you'll need to modify the `Info.plist` to add the following
```

Note that on iOS, this is a Swift plugin. There is a known issue being tracked [here](https://github.com/flutter/flutter/issues/16049) by the Flutter team, where adding a plugin developed in Swift to an Objective-C project causes problems. If you run into such issues, please look at the suggested workarounds there.

## macOS Integration (Beta)

Available for macOS 10.15+. Tested only on Intel based Macs.

Make sure, you enable 'Calendar' in the 'App Sandbox' section under 'Signing & Capabilities' in Xcode.
Original file line number Diff line number Diff line change
@@ -1,8 +1,21 @@
import EventKit
import Foundation

#if os(macOS)
import FlutterMacOS
#elseif os(iOS)
import EventKitUI
import Flutter
import Foundation
import UIKit
#endif

#if os(macOS)
typealias XColor = NSColor
typealias EKEventViewDelegate = NSObject
typealias UINavigationControllerDelegate = NSObject
#elseif os(iOS)
typealias XColor = UIColor
#endif

extension Date {
var millisecondsSinceEpoch: Double { return self.timeIntervalSince1970 * 1000.0 }
Expand All @@ -23,7 +36,16 @@ extension String {
}
}

public class SwiftDeviceCalendarPlugin: NSObject, FlutterPlugin, EKEventViewDelegate, UINavigationControllerDelegate {
#if os(macOS)
public class DeviceCalendarPluginBase: NSObject {}
#elseif os(iOS)
public class DeviceCalendarPluginBase: NSObject, EKEventViewDelegate, UINavigationControllerDelegate {

public func eventViewController(_ controller: EKEventViewController, didCompleteWith action: EKEventViewAction) {}
}
#endif

public class DeviceCalendarPlugin: DeviceCalendarPluginBase, FlutterPlugin {
struct DeviceCalendar: Codable {
let id: String
let name: String
Expand Down Expand Up @@ -157,8 +179,12 @@ public class SwiftDeviceCalendarPlugin: NSObject, FlutterPlugin, EKEventViewDele
var flutterResult : FlutterResult?

public static func register(with registrar: FlutterPluginRegistrar) {
#if os(macOS)
let channel = FlutterMethodChannel(name: channelName, binaryMessenger: registrar.messenger)
#elseif os(iOS)
let channel = FlutterMethodChannel(name: channelName, binaryMessenger: registrar.messenger())
let instance = SwiftDeviceCalendarPlugin()
#endif
let instance = DeviceCalendarPlugin()
registrar.addMethodCallDelegate(instance, channel: channel)
}

Expand Down Expand Up @@ -220,10 +246,10 @@ public class SwiftDeviceCalendarPlugin: NSObject, FlutterPlugin, EKEventViewDele
let calendarColor = arguments[calendarColorArgument] as? String

if (calendarColor != nil) {
calendar.cgColor = UIColor(hex: calendarColor!)?.cgColor
calendar.cgColor = XColor(hex: calendarColor!)?.cgColor
}
else {
calendar.cgColor = UIColor(red: 255, green: 0, blue: 0, alpha: 0).cgColor // Red colour as a default
calendar.cgColor = XColor(red: 255, green: 0, blue: 0, alpha: 0).cgColor // Red colour as a default
}

guard let source = getSource() else {
Expand All @@ -248,12 +274,17 @@ public class SwiftDeviceCalendarPlugin: NSObject, FlutterPlugin, EKEventViewDele
let defaultCalendar = self.eventStore.defaultCalendarForNewEvents
var calendars = [DeviceCalendar]()
for ekCalendar in ekCalendars {
#if os(macOS)
let calendarColor = ekCalendar.color.rgb()!
#elseif os(iOS)
let calendarColor = UIColor(cgColor: ekCalendar.cgColor).rgb()!
#endif
let calendar = DeviceCalendar(
id: ekCalendar.calendarIdentifier,
name: ekCalendar.title,
isReadOnly: !ekCalendar.allowsContentModifications,
isDefault: defaultCalendar?.calendarIdentifier == ekCalendar.calendarIdentifier,
color: UIColor(cgColor: ekCalendar.cgColor).rgb()!,
color: calendarColor,
accountName: ekCalendar.source.title,
accountType: getAccountType(ekCalendar.source.sourceType))
calendars.append(calendar)
Expand Down Expand Up @@ -932,6 +963,7 @@ public class SwiftDeviceCalendarPlugin: NSObject, FlutterPlugin, EKEventViewDele
}

private func showEventModal(_ call: FlutterMethodCall, _ result: @escaping FlutterResult) {
#if os(iOS)
checkPermissionsThenExecute(permissionsGrantedAction: {
let arguments = call.arguments as! Dictionary<String, AnyObject>
let eventId = arguments[eventIdArgument] as! String
Expand All @@ -958,9 +990,11 @@ public class SwiftDeviceCalendarPlugin: NSObject, FlutterPlugin, EKEventViewDele
result(FlutterError(code: self.genericError, message: self.eventNotFoundErrorMessageFormat, details: nil))
}
}, result: result)
#endif
}

public func eventViewController(_ controller: EKEventViewController, didCompleteWith action: EKEventViewAction) {
#if os(iOS)
override public func eventViewController(_ controller: EKEventViewController, didCompleteWith action: EKEventViewAction) {
controller.dismiss(animated: true, completion: nil)

if flutterResult != nil {
Expand All @@ -985,6 +1019,7 @@ public class SwiftDeviceCalendarPlugin: NSObject, FlutterPlugin, EKEventViewDele

return topController!
}
#endif

private func finishWithUnauthorizedError(result: @escaping FlutterResult) {
result(FlutterError(code:self.unauthorizedErrorCode, message: self.unauthorizedErrorMessage, details: nil))
Expand Down Expand Up @@ -1048,7 +1083,25 @@ extension Date {
}
}

extension UIColor {
extension XColor {
#if os(macOS)
func rgb() -> Int? {
let ciColor:CIColor = CIColor(color: self)!
let fRed : CGFloat = ciColor.red
let fGreen : CGFloat = ciColor.green
let fBlue : CGFloat = ciColor.blue
let fAlpha: CGFloat = ciColor.alpha

let iRed = Int(fRed * 255.0)
let iGreen = Int(fGreen * 255.0)
let iBlue = Int(fBlue * 255.0)
let iAlpha = Int(fAlpha * 255.0)

// (Bits 24-31 are alpha, 16-23 are red, 8-15 are green, 0-7 are blue).
let rgb = (iAlpha << 24) + (iRed << 16) + (iGreen << 8) + iBlue
return rgb
}
#elseif os(iOS)
func rgb() -> Int? {
var fRed : CGFloat = 0
var fGreen : CGFloat = 0
Expand All @@ -1068,6 +1121,7 @@ extension UIColor {
return nil
}
}
#endif

public convenience init?(hex: String) {
let r, g, b, a: CGFloat
Expand Down
8 changes: 8 additions & 0 deletions example/android/app/src/debug/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.builttoroam.device_calendar_example">
<!-- The INTERNET permission is required for development. Specifically,
the Flutter tool needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Modify this file to customize your launch splash screen -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="?android:colorBackground" />

<!-- You can insert your own image assets here -->
<!-- <item>
<bitmap
android:gravity="center"
android:src="@mipmap/launch_image" />
</item> -->
</layer-list>
18 changes: 18 additions & 0 deletions example/android/app/src/main/res/values-night/styles.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on -->
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
the Flutter engine draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
</style>
</resources>
8 changes: 8 additions & 0 deletions example/android/app/src/profile/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.builttoroam.device_calendar_example">
<!-- The INTERNET permission is required for development. Specifically,
the Flutter tool needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>
2 changes: 1 addition & 1 deletion example/ios/Flutter/AppFrameworkInfo.plist
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,6 @@
<string>arm64</string>
</array>
<key>MinimumOSVersion</key>
<string>9.0</string>
<string>11.0</string>
</dict>
</plist>
2 changes: 1 addition & 1 deletion example/ios/Podfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Uncomment this line to define a global platform for your project
platform :ios, '9.0'
platform :ios, '11.0'

# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
Expand Down
4 changes: 2 additions & 2 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/integration_test/ios"

SPEC CHECKSUMS:
device_calendar: 9cb33f88a02e19652ec7b8b122ca778f751b1f7b
device_calendar: faf934b9b8622694e80a8afded4d4a6f5e97f146
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
flutter_native_timezone: 5f05b2de06c9776b4cc70e1839f03de178394d22
integration_test: a1e7d09bd98eca2fc37aefd79d4f41ad37bdbbe5

PODFILE CHECKSUM: d3740c426905916d1f2ada0ddfce28cc99f7b7af
PODFILE CHECKSUM: 10625bdc9b9ef8574174815aabd5b048e6e29bff

COCOAPODS: 1.11.3
21 changes: 14 additions & 7 deletions example/ios/Runner.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objectVersion = 54;
objects = {

/* Begin PBXBuildFile section */
Expand Down Expand Up @@ -161,12 +161,11 @@
97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1240;
LastUpgradeCheck = 1300;
ORGANIZATIONNAME = "The Chromium Authors";
TargetAttributes = {
97C146ED1CF9000F007C117D = {
CreatedOnToolsVersion = 7.3.1;
DevelopmentTeam = PG8Q9ZR89L;
LastSwiftMigration = 1130;
ProvisioningStyle = Automatic;
};
Expand Down Expand Up @@ -229,6 +228,7 @@
};
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
Expand All @@ -243,6 +243,7 @@
};
9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
Expand Down Expand Up @@ -355,7 +356,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
Expand Down Expand Up @@ -405,7 +406,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
Expand All @@ -430,7 +431,10 @@
"$(PROJECT_DIR)/Flutter",
);
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
Expand Down Expand Up @@ -462,7 +466,10 @@
"$(PROJECT_DIR)/Flutter",
);
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreviewsEnabled</key>
<false/>
</dict>
</plist>
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1240"
LastUpgradeVersion = "1300"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreviewsEnabled</key>
<false/>
</dict>
</plist>
Loading