Skip to content

Commit f787c5b

Browse files
committed
fix #312
1 parent eb92075 commit f787c5b

File tree

3 files changed

+80
-98
lines changed

3 files changed

+80
-98
lines changed

README.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# open_file
2-
[![pub package](https://img.shields.io/pub/v/open_file.svg)](https://pub.dartlang.org/packages/open_file) [![Discord](https://img.shields.io/badge/discord-FlutterDev-blue.svg)](https://discord.gg/q6yFDws3Xc)
2+
[![pub package](https://img.shields.io/pub/v/open_file.svg)](https://pub.dartlang.org/packages/open_file) [![Discord](https://img.shields.io/badge/discord-FlutterDev-green.svg)](https://discord.gg/q6yFDws3Xc)
33

44
A plug-in that can call native APP to open files with string result in flutter, support iOS(DocumentInteraction) / android(intent) / PC(ffi) / web(dart:html)
55

@@ -185,3 +185,11 @@ subprojects {
185185
{".pdf", "com.adobe.pdf"}
186186
}
187187
```
188+
### MacOS
189+
add this to the entitlements file
190+
```
191+
<key>com.apple.security.app-sandbox</key>
192+
<true/>
193+
<key>com.apple.security.files.user-selected.read-only</key>
194+
<true/>
195+
```

open_file_mac/macos/Classes/OpenFilePlugin.swift

Lines changed: 70 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -12,35 +12,88 @@ public class OpenFilePlugin: NSObject, FlutterPlugin {
1212
switch call.method {
1313
case "open_file":
1414
let arguments = call.arguments as? Dictionary<String,Any>
15-
let filePath = arguments!["file_path"]
15+
let filePath = arguments!["file_path"] as? String
1616
if(filePath==nil){
17-
let map = ["message":"the file path cannot be null", "type":-4] as [String : Any]
18-
result(convertDictionaryToString(dict:map))
17+
self.result(result:result,message:"the file path cannot be null",type:-4)
1918
return
2019
}
21-
let fileExist = FileManager.default.fileExists(atPath: filePath as! String)
20+
let fileExist = FileManager.default.fileExists(atPath: filePath!)
2221
if(fileExist){
23-
let documentURL = URL(fileURLWithPath: filePath as! String )
22+
let documentURL = URL(fileURLWithPath: filePath!)
2423
let fileType = documentURL.pathExtension
25-
canOpen(fileURL: documentURL){b in
26-
DispatchQueue.main.async{
27-
if(!b){
28-
self.openSelectPanel(filePath:filePath as! String,fileType: fileType ,result: result)
29-
}else{
30-
self.open(documentURL: documentURL, result: result)
31-
}
32-
}
33-
24+
if(!canOpen(filePath: filePath!)){
25+
self.openSelectPanel(filePath:filePath!,fileType: fileType ,result: result)
26+
}else{
27+
self.open(documentURL: documentURL, result: result)
3428
}
35-
36-
29+
}else{
30+
self.result(result:result,message:"the file does not exist",type:-2)
3731
}
3832

3933
default:
4034
result(FlutterMethodNotImplemented)
4135
}
4236
}
4337

38+
private func canOpen(filePath: String) ->Bool{
39+
return FileManager.default.isReadableFile(atPath: filePath)
40+
}
41+
42+
private func convertDictionaryToString(dict:[String:Any]) -> String {
43+
var result:String = ""
44+
do {
45+
let jsonData = try JSONSerialization.data(withJSONObject: dict, options: JSONSerialization.WritingOptions.init(rawValue: 0))
46+
47+
if let JSONString = String(data: jsonData, encoding: String.Encoding.utf8) {
48+
result = JSONString
49+
}
50+
51+
} catch {
52+
result = ""
53+
}
54+
return result
55+
}
56+
57+
private func openSelectPanel(filePath:String,fileType: String,result: @escaping FlutterResult){
58+
let fileUrl = URL(fileURLWithPath:filePath)
59+
let openPanel = NSOpenPanel()
60+
openPanel.canChooseFiles = false
61+
openPanel.canChooseDirectories = true
62+
openPanel.allowsMultipleSelection = false
63+
openPanel.allowedFileTypes = [fileType]
64+
openPanel.directoryURL = fileUrl
65+
openPanel.showsHiddenFiles = true
66+
openPanel.allowsOtherFileTypes = false
67+
let currentLanguage = Locale.current.languageCode
68+
openPanel.prompt = (currentLanguage == "zh") ?"允许":"Accept"
69+
openPanel.beginSheetModal(for: NSApplication.shared.mainWindow!) { (openResult) in
70+
if (openResult.rawValue == NSApplication.ModalResponse.OK.rawValue) {
71+
let selectedURL = openPanel.url!
72+
var isReadable: Bool = false
73+
if FileManager.default.fileExists(atPath: selectedURL.path, isDirectory: nil) && FileManager.default.isReadableFile(atPath: selectedURL.path) {
74+
isReadable = true
75+
}
76+
if isReadable {
77+
self.open(documentURL: fileUrl, result: result)
78+
} else {
79+
self.result(result:result,message:"Operation not permitted",type:-3)
80+
}
81+
}else{
82+
self.result(result:result,message:"Operation not permitted",type:-3)
83+
}
84+
}
85+
}
86+
87+
private func open(documentURL:URL,result: FlutterResult){
88+
NSWorkspace.shared.open([documentURL], withAppBundleIdentifier: nil, options: .default, additionalEventParamDescriptor: nil, launchIdentifiers: nil)
89+
self.result(result:result,message:"done",type:0)
90+
}
91+
92+
private func result(result: FlutterResult,message:String,type:Int){
93+
let map = ["message":message, "type":type]as [String : Any]
94+
result(convertDictionaryToString(dict: map))
95+
}
96+
4497
@available(*, deprecated, message: "This method is just test.")
4598
private func requestDiskPermission(onGranted:()->Void,onDenied:()->Void){
4699

@@ -59,7 +112,7 @@ public class OpenFilePlugin: NSObject, FlutterPlugin {
59112
if (status != true) {
60113
print("Prompting for accessibility permissions")
61114
let alert = NSAlert()
62-
alert.messageText = "This app requires accessibility permissions to function properly. Please grant access in the System Preferences app when prompted."
115+
alert.messageText = "This app requires disk permissions to function properly. Please grant access in the System Preferences app when prompted."
63116
alert.addButton(withTitle: "OK")
64117
alert.runModal()
65118
onDenied()
@@ -87,85 +140,6 @@ public class OpenFilePlugin: NSObject, FlutterPlugin {
87140
}
88141
}
89142

90-
91-
private func canOpen(fileURL: URL,completeHandler:@escaping (Bool)->Void) {
92-
guard let workspace = NSWorkspace.shared.urlForApplication(toOpen: fileURL) else {
93-
// no app found to open
94-
completeHandler(false)
95-
return
96-
}
97-
98-
//Can the app be opened normally
99-
if #available(macOS 10.15, *) {
100-
let configuration = NSWorkspace.OpenConfiguration()
101-
configuration.activates = false
102-
103-
NSWorkspace.shared.open(
104-
[fileURL],
105-
withApplicationAt: workspace,
106-
configuration: configuration,
107-
completionHandler: { _, error in
108-
if let error = error {
109-
print("Error opening file:", error.localizedDescription)
110-
completeHandler(false)
111-
}else{
112-
completeHandler(true)
113-
}
114-
}
115-
)
116-
}
117-
118-
119-
}
120-
121-
private func convertDictionaryToString(dict:[String:Any]) -> String {
122-
var result:String = ""
123-
do {
124-
let jsonData = try JSONSerialization.data(withJSONObject: dict, options: JSONSerialization.WritingOptions.init(rawValue: 0))
125-
126-
if let JSONString = String(data: jsonData, encoding: String.Encoding.utf8) {
127-
result = JSONString
128-
}
129-
130-
} catch {
131-
result = ""
132-
}
133-
return result
134-
}
135-
136-
private func openSelectPanel(filePath:String,fileType: String,result: @escaping FlutterResult){
137-
138-
let openPanel = NSOpenPanel()
139-
openPanel.canChooseFiles = true
140-
openPanel.canChooseDirectories = false
141-
openPanel.allowsMultipleSelection = false
142-
openPanel.allowedFileTypes = [fileType]
143-
openPanel.directoryURL = URL(fileURLWithPath:filePath)
144-
openPanel.showsHiddenFiles = true
145-
openPanel.allowsOtherFileTypes = false
146-
openPanel.beginSheetModal(for: NSApplication.shared.mainWindow!) { (openResult) in
147-
if (openResult.rawValue == NSApplication.ModalResponse.OK.rawValue) {
148-
let selectedURL = openPanel.url!
149-
var isReadable: ObjCBool = false
150-
if FileManager.default.fileExists(atPath: selectedURL.path, isDirectory: nil) && FileManager.default.isReadableFile(atPath: selectedURL.path) {
151-
isReadable = true
152-
}
153-
if isReadable.boolValue {
154-
self.open(documentURL: selectedURL, result: result)
155-
} else {
156-
let map = ["message":"Operation not permitted", "type":-4] as [String : Any]
157-
result(self.convertDictionaryToString(dict:map))
158-
}
159-
}
160-
}
161-
}
162-
163-
private func open(documentURL:URL,result: FlutterResult){
164-
NSWorkspace.shared.open([documentURL], withAppBundleIdentifier: nil, options: .default, additionalEventParamDescriptor: nil, launchIdentifiers: nil)
165-
let map = ["message":"done", "type":0]as [String : Any]
166-
result(convertDictionaryToString(dict: map))
167-
}
168-
169143
@available(*, deprecated, message: "This method is no longer used.")
170144
private func getUTI(fileType:String)->String{
171145
var uti = ""

open_file_mac/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name: open_file_mac
22
description: MacOS implementation of the open_file plugin.
33
repository: https://github.com/crazecoder/open_file/tree/master/open_file_macos
4-
version: 1.0.2
4+
version: 1.0.3
55

66
environment:
77
sdk: ">=2.17.0 <4.0.0"

0 commit comments

Comments
 (0)