@@ -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 = " "
0 commit comments