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

Open App settings in iOS #5

Merged
merged 6 commits into from
Jul 27, 2018
Merged
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
2 changes: 2 additions & 0 deletions example/ios/Flutter/Debug.xcconfig
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "Generated.xcconfig"

FLUTTER_BUILD_MODE=debug
12 changes: 6 additions & 6 deletions example/ios/Runner.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; };
9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; };
9740EEB51CF90195004384FC /* Generated.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB31CF90195004384FC /* Generated.xcconfig */; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
Expand Down Expand Up @@ -174,7 +172,7 @@
97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0910;
LastUpgradeCheck = 0940;
ORGANIZATIONNAME = "The Chromium Authors";
TargetAttributes = {
97C146ED1CF9000F007C117D = {
Expand Down Expand Up @@ -207,9 +205,7 @@
buildActionMask = 2147483647;
files = (
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
9740EEB51CF90195004384FC /* Generated.xcconfig in Resources */,
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */,
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
2D5378261FAA1A9400D5DBA9 /* flutter_assets in Resources */,
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
Expand All @@ -226,7 +222,7 @@
);
inputPaths = (
"${SRCROOT}/Pods/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh",
"${PODS_ROOT}/../.symlinks/flutter/ios-release/Flutter.framework",
"${PODS_ROOT}/../.symlinks/flutter/ios/Flutter.framework",
"${BUILT_PRODUCTS_DIR}/permission_handler/permission_handler.framework",
);
name = "[CP] Embed Pods Frameworks";
Expand Down Expand Up @@ -333,12 +329,14 @@
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
Expand Down Expand Up @@ -387,12 +385,14 @@
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0910"
LastUpgradeVersion = "0940"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand All @@ -26,7 +26,6 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
Expand All @@ -46,7 +45,6 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
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>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
28 changes: 28 additions & 0 deletions example/ios/Runner/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>arm64</string>
</array>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
Expand Down Expand Up @@ -41,5 +45,29 @@
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Can I haz location?</string>
<key>NSAppleMusicUsageDescription</key>
<string>Music!</string>
<key>NSBluetoothPeripheralUsageDescription</key>
<string>bluetooth</string>
<key>NSCalendarsUsageDescription</key>
<string>Calendars</string>
<key>NSCameraUsageDescription</key>
<string>camera</string>
<key>NSContactsUsageDescription</key>
<string>contacts</string>
<key>kTCCServiceMediaLibrary</key>
<string>media</string>
<key>NSMicrophoneUsageDescription</key>
<string>microphone</string>
<key>NSMotionUsageDescription</key>
<string>motion</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>photos</string>
<key>NSRemindersUsageDescription</key>
<string>reminders</string>
<key>NSSpeechRecognitionUsageDescription</key>
<string>speech</string>
</dict>
</plist>
3 changes: 3 additions & 0 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class _MyAppState extends State<MyApp> {
permissionStatus = await PermissionHandler
.checkPermissionStatus(PermissionGroup.calendar);

/*
if (permissionStatus != PermissionStatus.granted) {
final bool shouldShowRationale = await PermissionHandler
.shouldShowRequestPermissionRationale(PermissionGroup.calendar);
Expand All @@ -38,11 +39,13 @@ class _MyAppState extends State<MyApp> {
final Map<PermissionGroup, PermissionStatus> permissions =
await PermissionHandler.requestPermissions(
<PermissionGroup>[PermissionGroup.calendar]);

if (permissions.containsKey(PermissionGroup.calendar)) {
permissionStatus = permissions[PermissionGroup.calendar];
}
}
}
*/
} on PlatformException {
permissionStatus = PermissionStatus.unknown;
}
Expand Down
63 changes: 63 additions & 0 deletions ios/Classes/PermissionManager.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
//
// PermissionManager.swift
// permission_handler
//
// Created by Maurits van Beusekom on 26/07/2018.
//

import Flutter
import Foundation
import UIKit

class PermissionManager: NSObject {

static func checkPermissionStatus(permission: PermissionGroup, result: @escaping FlutterResult) {
let permissionStrategy = PermissionManager.createPermissionStrategy(permission: permission)
let permissionStatus = permissionStrategy.checkPermissionStatus(permission: permission)

result(Codec.encodePermissionStatus(permissionStatus: permissionStatus))
}

static func openAppSettings(result: @escaping FlutterResult) {
if #available(iOS 8.0, *) {
if #available(iOS 10, *) {
UIApplication.shared.open(URL.init(string: UIApplicationOpenSettingsURLString)!, options: [:],
completionHandler: {
(success) in result(success)
})
} else {
let success = UIApplication.shared.openURL(URL.init(string: UIApplicationOpenSettingsURLString)!)
result(success)
}
}

result(false)
}

private static func createPermissionStrategy(permission: PermissionGroup) -> PermissionStrategy {
switch permission {
case PermissionGroup.calendar:
return EventPermissionStrategy()
case PermissionGroup.camera:
return AudioVideoPermissionStrategy()
case PermissionGroup.contacts:
return ContactPermissionStrategy()
case PermissionGroup.location,
PermissionGroup.locationAlways,
PermissionGroup.locationWhenInUse:
return LocationPermissionStrategy()
case PermissionGroup.mediaLibrary:
return MediaLibraryPermissionStrategy()
case PermissionGroup.microphone:
return AudioVideoPermissionStrategy()
case PermissionGroup.photos:
return PhotoPermissionStrategy()
case PermissionGroup.reminders:
return EventPermissionStrategy()
case PermissionGroup.sensors:
return SensorPermissionStrategy()
case PermissionGroup.speech:
return SpeechPermissionStrategy()
}
}
}
32 changes: 24 additions & 8 deletions ios/Classes/SwiftPermissionHandlerPlugin.swift
Original file line number Diff line number Diff line change
@@ -1,14 +1,30 @@

import CoreLocation
import CoreMotion
import EventKit
import Flutter
import Foundation
import Photos
import UIKit

public class SwiftPermissionHandlerPlugin: NSObject, FlutterPlugin {
public static func register(with registrar: FlutterPluginRegistrar) {
let channel = FlutterMethodChannel(name: "permission_handler", binaryMessenger: registrar.messenger())
let instance = SwiftPermissionHandlerPlugin()
registrar.addMethodCallDelegate(instance, channel: channel)
}
private static let METHOD_CHANNEL_NAME = "flutter.baseflow.com/permissions/methods";

public static func register(with registrar: FlutterPluginRegistrar) {
let channel = FlutterMethodChannel(name: METHOD_CHANNEL_NAME, binaryMessenger: registrar.messenger())
let instance = SwiftPermissionHandlerPlugin()
registrar.addMethodCallDelegate(instance, channel: channel)
}

public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
result("iOS " + UIDevice.current.systemVersion)
}
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
if call.method == "checkPermissionStatus" {
PermissionManager.checkPermissionStatus(
permission: Codec.decodePermissionGroup(from: call.arguments),
result: result)
} else if call.method == "openAppSettings" {
PermissionManager.openAppSettings(result: result)
} else {
result(FlutterMethodNotImplemented)
}
}
}
23 changes: 23 additions & 0 deletions ios/Classes/data/PermissionGroup.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//
// PermissionGroup.swift
// permission_handler
//
// Created by Maurits van Beusekom on 25/07/2018.
//

import Foundation

enum PermissionGroup : String, Codable {
case calendar = "calendar"
case camera = "camera"
case contacts = "contacts"
case location = "location"
case locationAlways = "locationAlways"
case locationWhenInUse = "locationWhenInUse"
case mediaLibrary = "mediaLibrary"
case microphone = "microphone"
case photos = "photos"
case reminders = "reminders"
case sensors = "sensors"
case speech = "speech"
}
16 changes: 16 additions & 0 deletions ios/Classes/data/PermissionStatus.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//
// PermissionStatus.swift
// permission_handler
//
// Created by Maurits van Beusekom on 25/07/2018.
//

import Foundation

enum PermissionStatus : String, Codable {
case denied = "denied"
case disabled = "disabled"
case granted = "granted"
case restricted = "restricted"
case unknown = "unknown"
}
41 changes: 41 additions & 0 deletions ios/Classes/strategies/AudioVideoPermissionStrategy.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
//
// AudioVideoPermissions.swift
// permission_handler
//
// Created by Maurits van Beusekom on 26/07/2018.
//
import AVFoundation
import Foundation

class AudioVideoPermissionStrategy : NSObject, PermissionStrategy {

func checkPermissionStatus(permission: PermissionGroup) -> PermissionStatus {
if permission == PermissionGroup.camera {
return AudioVideoPermissionStrategy.getPermissionStatus(mediaType: AVMediaType.video)
} else if permission == PermissionGroup.microphone {
return AudioVideoPermissionStrategy.getPermissionStatus(mediaType: AVMediaType.audio)
}

return PermissionStatus.unknown
}

func requestPermission(permission: PermissionGroup) -> PermissionStatus {
// TODO: Add implementation
return PermissionStatus.unknown
}

private static func getPermissionStatus(mediaType: AVMediaType) -> PermissionStatus {
let status: AVAuthorizationStatus = AVCaptureDevice.authorizationStatus(for: mediaType)

switch status {
case AVAuthorizationStatus.authorized:
return PermissionStatus.granted
case AVAuthorizationStatus.denied:
return PermissionStatus.denied
case AVAuthorizationStatus.restricted:
return PermissionStatus.restricted
default:
return PermissionStatus.unknown
}
}
}
36 changes: 36 additions & 0 deletions ios/Classes/strategies/ContactPermissionStrategy.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//
// ContactPermissions.swift
// permission_handler
//
// Created by Maurits van Beusekom on 26/07/2018.
//

import AddressBook
import Foundation

class ContactPermissionStrategy : NSObject, PermissionStrategy {

func checkPermissionStatus(permission: PermissionGroup) -> PermissionStatus {
return ContactPermissionStrategy.getPermissionStatus()
}

func requestPermission(permission: PermissionGroup) -> PermissionStatus {
// TODO: Add implementation
return PermissionStatus.unknown
}

private static func getPermissionStatus() -> PermissionStatus {
let status: ABAuthorizationStatus = ABAddressBookGetAuthorizationStatus()

switch status {
case ABAuthorizationStatus.authorized:
return PermissionStatus.granted
case ABAuthorizationStatus.denied:
return PermissionStatus.denied
case ABAuthorizationStatus.restricted:
return PermissionStatus.restricted
default:
return PermissionStatus.unknown
}
}
}
Loading