netfs - Mounting Volumes Asynchronously in Swift -
i trying port method mount volumes asynchronous, objective c swift. run problem lines of code. hope can give me answer.
the problems : knauioptionkey, knauioptionnoui , knetfsuseguestkey: unresolved identifiers. can't find equivalent in swift.
kcfbooleantrue : cfboolean not convertible unsafepointer.
code between /* , */ hard convert swift , that's help welcome.
import foundation import cocoa import netfs func mountvolumeasync(#username:string, #password:string, #ipadres:string, #proto:string, #mountpoint:string) -> bool{ var theurlpath: nsurl if username.lowercasestring == "guest" { println("volume mounted invitee user.....") allow thestring = "\(proto)://\(ipadres)/\(mountpoint)" allow theurlpath = nsurl(string:thestring) if theurlpath == nil { println("path file invalid.") homecoming false } } else { allow thestring = "\(proto)://\(username):\(password)@\(ipadres)/\(mountpoint)" allow theurlpath = nsurl( string:thestring) if theurlpath == nil { println("path file invalid.") homecoming false } } var mount_options = cfdictionarycreatemutable( kcfallocatordefault, 0, nil, nil); if (mount_options != nil) { cfdictionarysetvalue(mount_options, knauioptionkey, knauioptionnoui); if username.lowercasestring == "guest" { cfdictionarysetvalue( mount_options, knetfsuseguestkey, kcfbooleantrue); } } var status = false /* ---- objective c code port swift code ------ asyncrequestid requestid = null; dispatch_queue_t queue =dispatch_get_main_queue(); netfsmounturlasync( cfbridgingretain(theurlpath), null, (__bridge cfstringref) username, (__bridge cfstringref) passwd, mount_options, null, &requestid, queue, ^(int status, asyncrequestid requestid, cfarrayref mountpoints) { nslog(@"mounted: %d - %@", status, (__bridge nsarray *) mountpoints); }); if (!status) { nsstring *msg = [nsstring stringwithformat:@"[%@] not mounted! check params",mntpt]; homecoming no; } */ homecoming status }
i still trying solve problem, unfortunately not succeed. nobody answered question , still looking answer. changed code next , compiles, not run. while debugging find next error :
printing description of open_options:
(cfmutabledictionary!) open_options = 1 key/value pair { [0] = <execution interrupted, reason: exc_bad_access (code=1, address=0x4f4955414e80). process has been returned state before look evaluation.>
i found info in netfs framework:
the next dictionary keys open_options supported: knetfsuseguestkey: login invitee user. knetfsallowloopbackkey allow loopback mount.knauioptionkey = uioption suppress authentication dialog ui. *
the next dictionary keys mount_options supported:
knetfsmountflagskey = mnt_dontbrowse no browsable info here (see ). knetfsmountflagskey = mnt_rdonly read-only mount (see ). knetfsallowsubmountskey = true allow mount dir beneath share point. knetfssoftmountkey = true mount "soft" failure semantics. knetfsmountatmountdirkey = true mount on specified mountpath instead of below it. note if knetfssoftmountkey isn't set, it's set true.i hope can help.
func mountvolumeasync(#username:string, #password:string, #ipadres:string, #proto:string, #mountpoint:string) -> bool{ var theurlpath: nsurl? = nil if username.lowercasestring == "guest" { // "volume mounted invitee user....." allow thestring = stringwithformat("%@://%@/%@",proto,ipadres,mountpoint) allow theurlpath = nsurl(string:thestring) if theurlpath == nil { println("path file invalid.") homecoming false } } else { allow thestring = stringwithformat("%@://%@:%@@%@/%@",proto,username,password,ipadres,mountpoint) allow theurlpath = nsurl(string:thestring) if theurlpath == nil { println("path file invalid.") homecoming false } } var mount_options = cfdictionarycreatemutable( kcfallocatordefault, 0, nil, nil); var open_options = cfdictionarycreatemutable( kcfallocatordefault, 0, nil, nil); if open_options != nil { cfdictionarysetvalue(open_options,"knauioptionkey","noui") } if (mount_options != nil) { //cfdictionarysetvalue(mount_options,knauioptionkey"uioption") if username.lowercasestring == "guest" { allow knetfsuseguestkey = "guest" //cfdictionarysetvalue( mount_options, knetfsuseguestkey, kcfbooleantrue); cfdictionarysetvalue(open_options,knetfsuseguestkey, "kcfbooleantrue") } } var status = false var requestid: asyncrequestid = nil allow queue = dispatch_get_main_queue() netfsmounturlasync( theurlpath, nil, username nsstring, password nsstring, mount_options, open_options, &requestid, queue) {(stat:int32, requestid:asyncrequestid, mountpoints:cfarray!) -> void in println("mounted: \(stat) - \(mountpoints)") } if status == false { allow msg = "[\(mountpoint) not mounted! check params" println(msg) homecoming false } }
your swift code crashes because passing swift string function accepts unsafepointer
, such cfdictionarysetvalue
, pass pointer string character info encoded utf-8, not string object. additionally, character info valid until end of function call, after freed.
the symbols looking not exist in swift because depend on macro expansion. swift supports #define
dumb tokens (like #define foo 1
), not macros cfstr
. such key wish utilize needs copied on swift side. find value, utilize them in c/objective-c file , command-click them go definition. you'll find that:
#define knauioptionkey cfstr("uioption") #define knauioptionnoui cfstr("noui") #define knetfsuseguestkey cfstr("guest")
kcfbooleantrue
missing same reason (though doesn't utilize cfstr
).
you have 2 options bring cfstr
strings swift code. first , simplest declare values swift variables:
let knauioptionkey = "uioption" allow knauioptionnoui = "noui" allow knetfsuseguestkey = "guest"
the sec alternative expose values (with different name avoid clashing on c side of things) through bridging header:
nsstring* nauioptionkey; nsstring* nauioptionnoui; nsstring* netfsuseguestkey;
then have @ top level of objective-c file:
#include <netfs/netfs.h> nsstring* nauioptionkey = (nsstring*)knauioptionkey; nsstring* nauioptionnonui = (nsstring*)knauioptionnoui; nsstring* netfsuseguestkey = (nsstring*)knetfsuseguestkey;
nsstring
, cfstringref
same thing under hood. documented behavior casting 1 other fine (it's called toll-free bridging).
this solution forward-compatible because doesn't require know defined values expand to. apple theoretically alter string values between sdk versions, swift version break in future (though compiled binaries maintain working, , compiling against same sdk maintain working long apple supports it, it's not big deal).
kcfbooleantrue
same nsnumber(bool: true)
, because of toll-free bridging again.
similarly, nsdictionary
toll-free bridged cfdictionaryref
, encourage utilize instead of cfdictionary api, pain utilize swift because of void pointers. attractive in swift, because compiler recognizes nsdictionary*
, cfdictionaryref
same thing.
so be:
import foundation allow knauioptionkey = "uioption" allow knauioptionnoui = "noui" allow knetfsuseguestkey = "guest" func examplecfdictionary() -> cfdictionaryref { var dict = nsmutabledictionary() dict[knauioptionkey] = knauioptionnoui dict[knetfsuseguestkey] = nsnumber(bool: true) homecoming dict } println(examplecfdictionary())
i'm afraid you'll on own netfs itself, should pretty much solve dictionary woes. don't need separate function create dictionaries, did because simpler me copying code.
finally, encouraged create short, self-contained , right examples of you're having issues with. not lot of people know netfs, seems had issues swift , core foundation types more netfs. sscce, have reduced code these 3 lines:
var openoptions = cfdictionarycreatemutable(kcfallocatordefault, 0, nil, nil) cfdictionarysetvalue(openoptions, "knauioptionkey", "noui") println(openoptions)
a lot of people on here know what's wrong , you'd have had reply within minutes rather 3 months later.
swift netfs
No comments:
Post a Comment