this is my code in appDelegate didFinishLaunchingWithOptions()
var paths : NSArray = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
var documentsDirectory = paths.objectAtIndex(0)
var fileName: String = String(format: "Logger.txt")
var logFilePath : NSString = documentsDirectory.stringByAppendingPathComponent(fileName)
freopen(logFilePath, "a+", stderr)
the error am getting is cannot convert NSString to UnSafepointer.
can anyone help me how should i be implementing this ?
Just remove the NSString from the logFilePath:
var paths : NSArray = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
var documentsDirectory = paths.objectAtIndex(0)
var fileName: String = String(format: "Logger.txt")
var logFilePath = documentsDirectory.stringByAppendingPathComponent(fileName)
freopen(logFilePath, "a+", stderr)
And a more safer way to do this would be like this:
let file = "Logger.txt"
let text = "A safer way to do this"
if let directory : NSString = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.AllDomainsMask, true).first {
let path = directory.stringByAppendingPathComponent(file);
print(path)
do {
try text.writeToFile(path, atomically: false, encoding: NSUTF8StringEncoding)
}
catch {
}
}
Let go of the casting ;-)
All you need to cast is the NSArray to get you the objectAtIndex() method
let paths : NSArray = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
let documentsDirectory = paths.objectAtIndex(0)
let fileName = String(format: "Logger.txt")
let logFilePath = documentsDirectory.stringByAppendingPathComponent(fileName)
freopen(logFilePath, "a+", stderr)
Extra bonus: use let instead of var.
EDIT:
A version without NSArray & NSString:
let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
let documentsDirectory = paths[0]
let fileName = String(format: "Logger.txt")
let logFilePath = NSURL(fileURLWithPath: documentsDirectory).URLByAppendingPathComponent(fileName).absoluteString
freopen(logFilePath, "a+", stderr)
Related
So, i have an empty plist, i am trying to create these values in the plist
using this code :
let dictionary:[String:String] = ["key1" : "value1", "key2":"value2", "key3":"value3"]
let documentDirectoryURL = FileManager().urls(for: .documentDirectory, in: .userDomainMask).first!
let fileURL = documentDirectoryURL.appendingPathComponent("dictionary.plist")
if NSKeyedArchiver.archiveRootObject(dictionary, toFile: fileURL.path) {
print(true)
}
if let loadedDic = NSKeyedUnarchiver.unarchiveObject(withFile: fileURL.path) as? [String:String] {
print(loadedDic) // "["key1": "value1", "key2": "value2", "key3": "value3"]\n"
}
everything is fine here, but the question is, when i click the plist in my xcode project, its empty, these values are only printed not inserted to the plist
NSKeyedUnarchiver is the wrong way to save property lists.
There is a dedicated struct PropertyListSerialization to load and save property lists.
First declare a computed property plistURL
var plistURL : URL {
let documentDirectoryURL = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
return documentDirectoryURL.appendingPathComponent("dictionary.plist")
}
and two methods for loading and saving
func savePropertyList(_ plist: Any) throws
{
let plistData = try PropertyListSerialization.data(fromPropertyList: plist, format: .xml, options: 0)
try plistData.write(to: plistURL)
}
func loadPropertyList() throws -> [String:String]
{
let data = try Data(contentsOf: plistURL)
guard let plist = try PropertyListSerialization.propertyList(from: data, format: nil) as? [String:String] else {
return [:]
}
return plist
}
Create the dictionary and save it
do {
let dictionary = ["key1" : "value1", "key2":"value2", "key3":"value3"]
try savePropertyList(dictionary)
} catch {
print(error)
}
To update a value read it, update the value and save it back
do {
var dictionary = try loadPropertyList()
dictionary.updateValue("value4", forKey: "key4")
try savePropertyList(dictionary)
} catch {
print(error)
}
Have you tried using PropertyListEncoder instead of NSKeyedArchiver?
do {
try PropertyListEncoder().encode(dictionary).write(to: fileURL)
} catch {
print(error)
}
Decode:
do {
let data = try Data(contentsOf: fileURL)
try PropertyListDecoder().decode([String: String].self, from: data)
} catch {
// Handle error
}
Here is my answer
//MARK: User.plist Save & retrive data
func saveUserDataWithParams(userData: AnyObject) -> Void {
let documentsDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString
let path : NSString = documentsDirectory.appendingPathComponent("User.plist") as NSString
//userData.write(path as String, atomically: true)
userData.write(toFile: path as String, atomically: true)
}
func getUserPlistData() -> NSMutableDictionary {
let documentsDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString
let path : NSString = documentsDirectory.appendingPathComponent("User.plist") as NSString
let fileManager = FileManager.default
if (!(fileManager.fileExists(atPath: path as String)))
{
let documentsDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString
let path : NSString = documentsDirectory.appendingPathComponent("User.plist") as NSString
let data : NSMutableDictionary = NSMutableDictionary()
data.write(toFile: path as String, atomically: true)
}
let data : NSMutableDictionary = NSMutableDictionary(contentsOfFile: path as String)!
return data
}
I have a folder of images that were imported with Create Folder Reference method, since I want to call images with URLForResoure for transfer to Watch.
Before I transfer Images I would like to count them in folder.
I was able to get folderURL path with this code:
let documentsURL = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0]
let folderURL = documentsURL.URLByAppendingPathComponent("Folder/SubFolder", isDirectory: true)
but can not get access to files inside this folder.
I want to access files and count them either with same prefix or inside subfolder.
Please help.
Swift3
let fileManager = FileManager.default
let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as String
let dirContents = try? fileManager.contentsOfDirectory(atPath: documentsPath)
let count = dirContents?.count
if count == 0{
disableTabBarHistory()// or whatever...
}
here's a count of directory contents:
let fileManager = NSFileManager.defaultManager()
let documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as String
var dirContents = try? fileManager.contentsOfDirectoryAtPath(documentsPath)
let count = dirContents?.count
Swift 5.5:
let fileManager = FileManager.default
let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as String
let content = try? fileManager.contentsOfDirectory(atPath: path)
let count = content?.count
it's easy my friend
let fileManager = NSFileManager.defaultManager()
var error : NSError?
if let files = fileManager.contentsOfDirectoryAtPath(folde rURL, error: &error) {
let count = files.count
// ...
} else {
println("Could not get contents of directory: \(error?.localizedDescription)")
}
I solved my problem using this line of code:
let URL = NSBundle.mainBundle().URLsForResourcesWithExtension("jpg", subdirectory: "Folder/SubFolder")
let count = (excerciseImagesForAnimationURL?.count)!
I upgraded my code for Swift 2, here I got an error:
Cannot invoke initializer for type NSURL with an argument list of type (fileURLWithPath: NSURL)
Here's the code:
let dirPaths = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)
let docsDir = dirPaths[0]
let soundFilePath = NSURL(fileURLWithPath: docsDir).URLByAppendingPathComponent("sound.caf")
let soundFileURL = NSURL(fileURLWithPath: soundFilePath)
//The error goes here.
Syntax of fileURLWithPath:
public init(fileURLWithPath path: String)
Which means it only accept String as argument. And you are passing NSURL as an argument.
And you can solve it this way:
let dirPaths = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)
let docsDir = dirPaths[0]
let soundFilePath = (docsDir as NSString).stringByAppendingPathComponent("sound.caf")
let soundFileURL = NSURL(fileURLWithPath: soundFilePath)
And here is extension if you want to use:
extension String {
func stringByAppendingPathComponent(path: String) -> String {
return (self as NSString).stringByAppendingPathComponent(path)
}
}
And you can use it this way:
let soundFilePath = docsDir.stringByAppendingPathComponent("sound.caf")
let soundFileURL = NSURL(fileURLWithPath: soundFilePath)
You're trying to create an NSURL from an NSURL object, there is no initializer for that. To create the URL properly just replace
let soundFilePath = NSURL(fileURLWithPath: docsDir).URLByAppendingPathComponent("sound.caf")
let soundFileURL = NSURL(fileURLWithPath: soundFilePath)
with
let soundFileURL = NSURL(fileURLWithPath: docsDir).URLByAppendingPathComponent("sound.caf")
I am using the documents directory of my application to cache images locally, but when I go to access them, they are not updated until I close the app and reopen.
Here is my save:
var readPath = ""
let nsDocumentDirectory = NSSearchPathDirectory.DocumentDirectory
let nsUserDomainMask = NSSearchPathDomainMask.UserDomainMask
if let paths = NSSearchPathForDirectoriesInDomains(nsDocumentDirectory, nsUserDomainMask, true) {
if paths.count > 0 {
if let dirPath = paths[0] as? String {
readPath = dirPath.stringByAppendingPathComponent("\(user).png")
UIImagePNGRepresentation(imageView.image).writeToFile(readPath, atomically: true)
}
}
}
Here is my retrieval:
var readPath = ""
let nsDocumentDirectory = NSSearchPathDirectory.DocumentDirectory
let nsUserDomainMask = NSSearchPathDomainMask.UserDomainMask
if let paths = NSSearchPathForDirectoriesInDomains(nsDocumentDirectory, nsUserDomainMask, true) {
if paths.count > 0 {
if let dirPath = paths[0] as? String {
readPath = dirPath.stringByAppendingPathComponent("\(user).png")
//UIImagePNGRepresentation(imageView.image).writeToFile(readPath, atomically: true)
}
}
}
let cachedImage = UIImage(named: readPath)
if (cachedImage != nil)
{
println("cached")
self.userPictures.append(cachedImage!)
}
For some reason though, it is not until I have reset the application that these resources become available.
Can anyone shed some light on why this could be?
The image that gets returned to cachedImage is an image that I had previously saved into that specific path btw
This may helps you....
let fileManager = NSFileManager.defaultManager()
var paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as! String
var getImagePath = paths.stringByAppendingPathComponent("\(fileName).png")
if (fileManager.fileExistsAtPath(getImagePath))
{
println("FILE AVAILABLE");
//Pick Image and Use accordingly
var imageis: UIImage = UIImage(contentsOfFile: getImagePath)!
self.image = imageis // UIImageView Class
let datas: NSData = UIImagePNGRepresentation(imageis)
}
else
{
println("FILE NOT AVAILABLE");
let getImage = UIImage(data: self.data)
self.image = getImage
var filePathToWrite = "\(paths)/\(fileName).png"
var imageData: NSData = UIImagePNGRepresentation(self.image)
fileManager.createFileAtPath(filePathToWrite, contents: imageData, attributes: nil)
}
Check the Project in Github
Say I were using this code to save an image to the documents directroy
let nsDocumentDirectory = NSSearchPathDirectory.DocumentDirectory
let nsUserDomainMask = NSSearchPathDomainMask.UserDomainMask
if let paths = NSSearchPathForDirectoriesInDomains(nsDocumentDirectory, nsUserDomainMask, true) {
if paths.count > 0 {
if let dirPath = paths[0] as? String {
let readPath = dirPath.stringByAppendingPathComponent("Image.png")
let image = UIImage(named: readPath)
let writePath = dirPath.stringByAppendingPathComponent("Image2.png")
UIImagePNGRepresentation(image).writeToFile(writePath, atomically: true)
}
}
}
How would I then retrive it? Keeping in mind than in iOS8 the exact path changes often
You are finding the document directory path at runtime for writing the image, for reading it back, you can use the exact logic:
Swift 3 and Swift 4.2
let nsDocumentDirectory = FileManager.SearchPathDirectory.documentDirectory
let nsUserDomainMask = FileManager.SearchPathDomainMask.userDomainMask
let paths = NSSearchPathForDirectoriesInDomains(nsDocumentDirectory, nsUserDomainMask, true)
if let dirPath = paths.first
{
let imageURL = URL(fileURLWithPath: dirPath).appendingPathComponent("Image2.png")
let image = UIImage(contentsOfFile: imageURL.path)
// Do whatever you want with the image
}
Swift 2
let nsDocumentDirectory = NSSearchPathDirectory.DocumentDirectory
let nsUserDomainMask = NSSearchPathDomainMask.UserDomainMask
if let paths = NSSearchPathForDirectoriesInDomains(nsDocumentDirectory, nsUserDomainMask, true)
{
if paths.count > 0
{
if let dirPath = paths[0] as? String
{
let readPath = dirPath.stringByAppendingPathComponent("Image2.png")
let image = UIImage(contentsOfFile: readPath)
// Do whatever you want with the image
}
}
}
Better as an extension.
extension URL {
static var documentsDirectory: URL {
let documentsDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!
return try! documentsDirectory.asURL()
}
static func urlInDocumentsDirectory(with filename: String) -> URL {
return documentsDirectory.appendingPathComponent(filename)
}
}
Used like this:
let path = URL.urlInDocumentsDirectory(with: filename).path
let image = UIImage(contentsOfFile: path)
Load multiple images from the folder or directory. - Swift 4
Here's the image attached to show, what we want to achieve in the given below code.
Here's the code to find the multiple images from the folder in documents directory. I have written one method to do the same.
In the code we are passing the "Folder Name" (ie. Red) and getting the contents of that directory. In return we got the array of images name.
static func loadImagesFromAlbum(folderName:String) -> [String]{
let nsDocumentDirectory = FileManager.SearchPathDirectory.documentDirectory
let nsUserDomainMask = FileManager.SearchPathDomainMask.userDomainMask
let paths = NSSearchPathForDirectoriesInDomains(nsDocumentDirectory, nsUserDomainMask, true)
var theItems = [String]()
if let dirPath = paths.first
{
let imageURL = URL(fileURLWithPath: dirPath).appendingPathComponent(folderName)
do {
theItems = try FileManager.default.contentsOfDirectory(atPath: imageURL.path)
return theItems
} catch let error as NSError {
print(error.localizedDescription)
return theItems
}
}
return theItems
}
Here's the result of given code.
Hope it helps.
Thanks
Swift 2
If you want to get a file from your document directory in Swift 2:
let path: String? = NSBundle.mainBundle().pathForResource("imageName", ofType: "png", inDirectory: "DirectoryName/Images")
let imageFromPath = UIImage(contentsOfFile: path!)!
self.myImage.image = imageFromPath
Hope that helps somebody
// --------------------------------------------------------
// MARK:- Document Directory
// --------------------------------------------------------
///# Get Data from document directory #///
private func getDocumentData(){
///# Path #///
let folderPath = (NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString).appendingPathComponent("MyZipFiles") /// * folder *///
let filePath = URL(fileURLWithPath: folderPath).appendingPathComponent("\(self.id)/\(self.titleVideo)") ///* inside folder all files *///
print(filePath)
///# Get JsonFile from Directory with alamofire #///
let jsonFilePath = URL(fileURLWithPath: folderPath).appendingPathComponent("\(self.id)/\(self.titleVideo)/python.json") ///* inside filename *///
if (try! jsonFilePath.checkResourceIsReachable()) {
print("file exist")
Alamofire.request(jsonFilePath, method: .get, parameters: nil).responseData { (response) in
guard let data = response.data else { return }
do{
let json = try SwiftyJSON.JSON(data: data)
let results = json["images"]
for arr in results.arrayValue{
self.arrImageData.append(Images(json: arr))
}
self._pickerCollectionView.reloadData()
print(self.arrImageData)
}catch{
print(error.localizedDescription)
}
}
///# Back Video #///
let backVideoPath = URL(fileURLWithPath: folderPath).appendingPathComponent("\(self.id)/\(self.titleVideo)/background_video.mp4") ///* inside filename *///
print(backVideoPath)
///# Output Video #///
let outputPath = URL(fileURLWithPath: folderPath).appendingPathComponent("\(self.id)/\(self.titleVideo)/output.mp4")
print(outputPath)
///# Get images string from documentdirectory #///
do {
let imagesData = try FileManager.default.contentsOfDirectory(atPath: filePath.path) ///* Base Path to find Image *///
///# for loop to append path to find saved images and fill image array #///
for imgStr in imagesData{
if imgStr.hasPrefix("img"){
imagesArr.append(imgStr)
print(imagesArr)
let document = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true).appendingPathComponent("MyZipFiles")
print(document)
let loadImage = document.appendingPathComponent("\(self.id)/\(self.titleVideo)")
let imgUrl = loadImage.appendingPathComponent(imgStr, isDirectory: true)
print(imgUrl.path)
if let data = UIImage(named: imgStr)?.pngData() ,
!FileManager.default.fileExists(atPath: imgUrl.path){
do{
///* write data to convert string images into url in document folder *///
try data.write(to: imgUrl)
print("Image Add Successfully")
Log.debug(imgStr)
}
catch{
print("Image Not Added")
}
}
///* append written url into array of images *///
imgArr.append(imgUrl)
}
}
}
catch let err{
print(err.localizedDescription)
}
}
}