Monday 15 August 2011

netfs - Mounting Volumes Asynchronously in Swift -



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