Volver a la página inicial

Volver a la página anterior

// RGBiOSUtilitiesBundle

//

// Depends on RGBIOSUtilities.swift

//

// If prints for debugging must work, just add -D PRINT_FOR_DEBUGGING in Other Swift Flags

// (Cmd-1, click on project, enter Other Swift Flags in search field)

//

// Updated (headerdoc added) on 30-01-2018

//

import Foundation


//MARK: bundleReadAsString(fileName:,withExtension:) -> String


/// Read a text file that is in supposed to be in the bundle (not in a real folder in the bundle)

///

/// - Parameters:

///   - fileName: Name of a file in the bundle of this app

///   - fileExtension: Extension of this file in the bundle of this app

/// - Returns: Contents of the file as a String?, if the file does exist and can be read.

public func bundleReadAsString(fileName:String, withExtension fileExtension:String) -> String? {

  var text:String?

  //

  // If the file is not found in the bundle, the string

  // given back by this method will be nil

  //

  guard

    let temp = Bundle.main.url(forResource: fileName,

                               withExtension: fileExtension),

    !temp.hasDirectoryPath

    else { return nil }

  //

  // If we get here,there IS a file in the bundle with that name

  //

  do {

    text = try String(contentsOf: temp)

  } catch {

    text = nil

  }


  return text

} // End of bundleReadAsString()


//MARK: readAllLinesFromFile(fileName:withExtension:)

/// Emulates Files.readAllLines(). Returns an optional.

///

/// - Parameters:

///   - name: The name of the file, supposedly placed in the bundle of this app

///   - ext: extension of the file

/// - Returns: A [String]? that holds all lines from the file

public func bundleReadAllLinesFromFile(_ name:String, withExtension ext:String) -> [String]? {

  if let contents = bundleReadAsString(fileName: name, withExtension: ext) {

    return contents.components(separatedBy: "\n")

  } else {

    return nil

  }

} // End of bundleReadAllLinesFromFile(fileName:withExtension:)


//MARK: bundleReadAllLinesFromFile(_:,inFolder:withExtension:)

///

/// Emulates Files.readAllLines() for a file placed inside a folder in the bundle. Returns an optional.

///

/// - Parameters:

///   - name: Name of the file, supposed to be placed inside a real folder in the bundle

///   - folder: Name of the folder that holds the file, placed inside the bundle.

///   - ext: Extension of the file

/// - Returns: A [String]? taht holds all lines in the file.

public func bundleReadAllLinesFromFile(_ name:String,

                                       inFolder folder:String,

                                       withExtension ext:String) -> [String]? {


  if let contents = bundleReadAsStringFromFolder(folderName: folder,

                                                 fileName: name,

                                                 withExtension: ext) {

    return contents.components(separatedBy: "\n")

  } else {

    return nil

  }


} // End of bundleReadAllLinesFromFile(_:,inFolder:withExtensino)


//MARK: bundleReadAsStringFromFolder(_:,fileName:,withExtension:) -> String


/// Read a text file that is supposed to be in the bundle in a real folder, returning it as ONE optional String.

///

/// - Parameters:

///   - folderName: Name of the folder that holds the file, placed inside the bundle.

///   - fileName: Name of the file, supposed to be placed inside a real folder in the bundle

///   - fileExtension: Extension of the file

/// - Returns: One single line with the whole contents of the file placed in a folder in the bundle, as a single String?

public func bundleReadAsStringFromFolder(folderName:String,

                                         fileName:String,

                                         withExtension fileExtension:String) -> String? {

  var text:String? = nil


  if let temp = Bundle.main.url(forResource: fileName,

                                withExtension: fileExtension,

                                subdirectory: folderName) {

    do {

      text = try String(contentsOf: temp)

    } catch  {

      text = nil

    } // End of do/catch


  } // End of if/let

  return text

} // End of bundleReadAsStringFromFolder()



//MARK: shallowListingOfObjectsInBundle()

/// Gives back the names of all objects in the bundle directory (no recursive traversing), ready to be printed as text. Each name is complemented with a description that shows whether it is a file or a folder.

///

/// - Returns: An optional String with the names of all objects prepended with File: or Directory:. Each object is in one line.

public func shallowListingOfObjectsInBundle() -> String? {

  var text = ""


  //

  // MAIN ACCESS METHOD - URLs OF ITEMS IN BUNDLE

  //

  if let itemURLs = Bundle.main.urls(forResourcesWithExtension: nil,

                                     subdirectory: nil) {

    #if PRINT_FOR_DEBUGGING

      print(itemURLs)

    #endif


    itemURLs.forEach() {

      text.append( (isDirectory(url: $0) ? "Directory : " : "File      : ")

        + "\($0.lastPathComponent)"

        + "\n")

    } // End of forEach

    return text

  } // End of if let

  else {

    return nil

  }

} // End of shallowListingOfObjectsInBundle()


//MARK: deepListingOfRealDirectoryInBundle(_:) -> String?

/// Gives back a String? with the recursive listing of a real directory in the bundle, needs work

// Not yet well done

public func deepListingOfRealDirectoryInBundle(_ url:URL) -> String? {


  let nameOfSubdirectory = url.lastPathComponent

  var text = "Subdirectory " + nameOfSubdirectory + "\n"

  let directoryContents = Bundle.main.urls(forResourcesWithExtension: nil, subdirectory: nameOfSubdirectory)

  directoryContents?.forEach() {

    if isDirectory(url: $0) {

      text.append("Directory: \($0)\n")

    } else {

      text.append( "File      : "

        + "\($0.lastPathComponent)"

        + "\n")

    }

  }

  return text

} // End of deepListingOfRealDirectoryInBundle




//MARK: deepListingOfBundle() -> String?

/// Gives back a String? with the recursive listing of all objects the bundle

public func deepListingOfBundle() -> String? {

  var text = ""


  //

  // MAIN ACCESS METHOD - URLs OF ALL ITEMS IN BUNDLE

  //

  if let itemURLs = Bundle.main.urls(forResourcesWithExtension: nil,

                                     subdirectory: nil) {


    itemURLs.forEach() {

      if isDirectory(url: $0) {

        text.append("Directory \($0):\n")

      } else {

        text.append( ("File      : ")

          + "\($0)"

          + "\n")

      }

    } // End of forEach


  } // End of if let


  return text



} // End of deepListingOfBundle()




//MARK: deepListingOfDirectoriesInBundle() -> String?

/// Gives back a String? with the recursive listing of all objects of type directory in the bundle

func deepListingOfDirectoriesInBundle() -> String? {

  var text = ""

  let dfm = FileManager.default

  if  let bundleResourceURL = Bundle.main.resourceURL {


    if let itemURLs =   dfm.enumerator(at:  bundleResourceURL,

                                       includingPropertiesForKeys: []) {

      itemURLs.forEach() {

        let url = $0 as! URL

        if isDirectory(url: url) {

          text.append( url.absoluteString

            + "\n\n")

        }

      }

    } // End of forEach


  } // End of if let


  return text

} // End of deepListingOfDirectoriesInBundle()




//MARK: listingOfFilesInBundle(withExtension:) -> String?



/// The recursive listing of all files with a given extension in the bundle

///

/// - Parameter fileExtension: The extension of the files to be found in the bundle

/// - Returns: A String? that holds each of the files in the bundle with the given extension. Each file is in its own line.

func listingOfFilesInBundle(withExtension fileExtension:String) -> String? {

  var text:String?

  guard

    let itemURLs =   Bundle.main.urls(forResourcesWithExtension: fileExtension,

                                      subdirectory:nil),

    !itemURLs.isEmpty

    else {

      return nil

  } // End of guard


  itemURLs.forEach() { text?.append( $0.absoluteString + "\n\n") }

  return text

} // End of listingOfFilesInBundle()



// This method gives back the list of resources with a given extension that are stored inside a folder in the bundle. Do realize that a relative path into that folder is easy to build and lets the programmer access any file of a given type inside a given folder in the bundle, even when the final parent folder is nested 3 deep into the topmost one. In other words, folder denotes folder_path within the bundle.

//

// DEEP LISTINGS NOT WORKING YET

//

//MARK: listingOfBundleFilesInRealDirectory(_:withExtension:) -> String?


/// This method gives back the list of resources with a given extension that are stored inside a folder in the bundle. Do realize that a relative path into that folder is easy to build and lets the programmer access any file of a given type inside a given folder in the bundle, even when the final parent folder is nested 3 deep into the topmost one. In other words, folder denotes folder_path within the bundle.

///

/// - Parameters:

///   - folder: The path to a folder inside the bundle. It can hold a complex path inside the folder.

///   - fileExtension: The extension of the files to be found.

/// - Returns: A [String]? that holdes, in each line, the name of a file with the given extension. All files belong to the folder whose path is given as the first argument.

func listingOfBundleFilesInRealDirectory(folder:String,

                                         withExtension fileExtension:String) -> String? {

  var text:String?

  //

  // Just write the path to the subdirectory (folder media_blue) in the second argument

  //

  guard

    let itemURLs =   Bundle.main.urls(forResourcesWithExtension: fileExtension,

                                      subdirectory: folder),

    !itemURLs.isEmpty

    else {

      return nil

  } // End of guard


  itemURLs.forEach() { text?.append( $0.absoluteString + "\n\n") }

  return text

}