0

I apologise for the poor title, any changes are welcomed.

I have a function that checks the mounted external drives and prints them, that works perfectly, as the for loop loops printing each item out.

I want it to also return these drives concatenated as a string or an array. The problem is while it will print them all perfectly, it will only return the last item (as this is obviously the one left when the loop finished.

Any help getting it to return all mounted disks (not just the last one) would be wonderful.

func checkMountedDrives() -> String
{
    var volumeURLString = "unkmown"
    if let session = DASessionCreate(kCFAllocatorDefault) {
    let mountedVolumeURLs = FileManager.default.mountedVolumeURLs(includingResourceValuesForKeys: nil)!
    for volumeURL in mountedVolumeURLs {
        if let disk = DADiskCreateFromVolumePath(kCFAllocatorDefault, session, volumeURL as CFURL),
            let bsdName = DADiskGetBSDName(disk) {
            let bsdString = String(cString : bsdName)
            print("💾volumes ", volumeURL.path)
            volumeURLString = String(volumeURL.path)          
        }   
    }    
}
    return volumeURLString // this only returns the last item, I want them all!
}

Any help for a new (and very old) programmer would be gratefully recieved.

2
  • 1
    Return an array of String instead of a single String which you mention in your question. Commented Dec 9, 2022 at 4:13
  • var returrnedMountPaths: [String] = [] before the for loop,, then returrnedMountPaths.append(volumeURL.path) inside? Commented Dec 9, 2022 at 4:22

1 Answer 1

1
func checkMountedDrives() -> [String] {
    var volumeURLString: [String] = []
    if let session = DASessionCreate(kCFAllocatorDefault) {
        let mountedVolumeURLs = FileManager.default.mountedVolumeURLs(includingResourceValuesForKeys: nil)!
        for volumeURL in mountedVolumeURLs {
            if let disk = DADiskCreateFromVolumePath(kCFAllocatorDefault, session, volumeURL as CFURL),
                let bsdName = DADiskGetBSDName(disk) {
                let bsdString = String(cString: bsdName)
                print("💾volumes ", volumeURL.path)
                volumeURLString.append(String(volumeURL.path))        
            }   
        }    
    }
    return volumeURLString // this is all!
}

if you want both bsd and volume then make struct

struct BSDVolume {
    let bsd: String
    let volume: String
}

func checkMountedDrives() -> [BSDVolume] {
    var bsdVolume: [BSDVolume] = []
    if let session = DASessionCreate(kCFAllocatorDefault) {
        let mountedVolumeURLs = FileManager.default.mountedVolumeURLs(includingResourceValuesForKeys: nil)!
        for volumeURL in mountedVolumeURLs {
            if let disk = DADiskCreateFromVolumePath(kCFAllocatorDefault, session, volumeURL as CFURL),
                let bsdName = DADiskGetBSDName(disk) {
                let bsdString = String(cString: bsdName)
                print("💾volumes ", volumeURL.path)
                bsdVolume.append(BSDVolume(bsd: bsdString,volume: String(volumeURL.path))      
            }   
        }    
    }
    return bsdVolume // this is all!
}

print(checkMountedDrives().map(\.bsd)) // all bad
print(checkMountedDrives().map(\.volume)) // all volume
Sign up to request clarification or add additional context in comments.

6 Comments

FYI - The init in your struct is redundant. By default a struct gets an init for all of its properties if you don't define any explicit init methods.
I didn't get it can you explain simply please?
Remove the init method from your struct. It's not needed.
Yeah I think so I just copy paste a struct from my Mac and renamed it
Note that URL's path property returns a String. Initializing a new String from it is pointless.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.