I'm looking for the Swift equivalent of the following Objective C common code.
In Objective C we had the following to redirect logging to the document folder instead of to the console:
- (void) redirectConsoleLogToDocumentFolder
{
NSArray *paths =
NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,
YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *logPath = [documentsDirectory
stringByAppendingPathComponent:#"console.log"];
freopen([logPath
cStringUsingEncoding:NSASCIIStringEncoding],"a+",stderr);
}
How is that done in Swift 2 ?
I suggest to read about logging in swift
func redirectConsoleLogToDocumentFolder() {
var paths: NSArray = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
var documentsDirectory: NSString = paths[0]
var logPath: NSString = documentsDirectory.stringByAppendingPathComponent("console.log")
var cstr = (logPath as NSString).UTF8String
freopen(cstr, "a+", stderr)
}
An updated answer for Swift 3.0
if let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first {
let documentsDirectory = NSURL(fileURLWithPath: path)
let logPath = documentsDirectory.appendingPathComponent("console.log")!
freopen(logPath.absoluteString, "a+", stderr)
}
Related
I need to read the entire console output so i'd like to implement a functionality which will send everything that was printed out to my email or something like that.
Is it possible?
I do realize that I could just use a different function for logging print statements etc but i need the outputs from the 3rd party libs as well.
You can write the log to a file and then email it. I put the snippet here. Just one question, why would you want to retrieve the log by mail?
Objective-c
NSArray *allPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [allPaths objectAtIndex:0];
NSString *pathForLog = [documentsDirectory stringByAppendingPathComponent:#"logfile.log"];
freopen([pathForLog cStringUsingEncoding:NSASCIIStringEncoding],"a+",stderr);
Swift
let allPaths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
let documentsDirectory = allPaths.first!
let pathForLog = documentsDirectory.stringByAppendingString("/logfile.log")
freopen(pathForLog.cStringUsingEncoding(NSASCIIStringEncoding)!, "a+", stderr)
I have a video I'm fetching from my server and receiving as data. I'm trying to cover the raw data into a URL so that I can use it to instantiate an AVPlayerItem and play the video on the phone. However, this code returns nil when I print "videoDataString". If I print "videoData" there is a result though. Here is my code where I try to convert, is my mistake the encoding part?
let videoDataString = NSString(data: videoData, encoding: NSUTF8StringEncoding)
let videoURL = NSURL(string: String(videoDataString))
First Save your Video data to a file then try to access that as a file URL.
Here is an example.
NSString *filePath = [self documentsPathForFileName:#"video.mp4"];
NSData *videoAsData; // your data here
[videoAsData writeToFile:filePath atomically:YES];
// access video as URL
NSURL *videoFileURL = [NSURL fileURLWithPath:filePath];
- (NSString *)documentsPathForFileName:(NSString *)name
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0];
return [documentsPath stringByAppendingPathComponent:name];
}
For Swift 3.0:
let filePath = self.documentsPathForFileName("video.mp4")
let videoAsData = NSData()
videoAsData.write(toFile: filePath, atomically: true)
let videoFileURL = NSURL(fileURLWithPath: filePath)
func documentsPathForFileName(name: String) -> String {
let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
return documentsPath.appending(name)
}
You cannot convert all strings to URL. URL is Uniform Resource Locator. That means it is a string containing the path to the file or resource in remote or local destination. If you want to keep your video data and instantiate video player with that video, first save the video data to a file, then instantiate video player with path to that file.
Use following code for this
let documentsURL = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask).first!
let videoURL = documentsURL.URLByAppendingPathComponent("video.mp4")//what ever your filename and extention
videoData.writeToURL(videoURL, atomically: true)
//uese videoURL to instantiate video player
In my application I download PDF files which gets stored in "Document" directory under different sub folders.
Now I have file name for which I want to get its path in "Document" directory but problem is I don't know the exact sub folder under which that file is stored.
So is there any method which will give me file path by file's name like there is one method which works for main bundle:
(NSString *)pathForResource:(NSString *)name ofType:(NSString *)extension
I don't want to iterate through each folder which is a tedious way.
Thanks.
You can search the documents directory like this:
NSString *searchFilename = #"hello.pdf"; // name of the PDF you are searching for
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSDirectoryEnumerator *direnum = [[NSFileManager defaultManager] enumeratorAtPath:documentsDirectory];
NSString *documentsSubpath;
while (documentsSubpath = [direnum nextObject])
{
if (![documentsSubpath.lastPathComponent isEqual:searchFilename]) {
continue;
}
NSLog(#"found %#", documentsSubpath);
}
EDIT:
You can also use NSPredicate. If there are many thousands of files in the documents directory, this might crash with an out of memory error.
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"self.lastPathComponent == %#", searchFilename];
NSArray *matchingPaths = [[[NSFileManager defaultManager] subpathsAtPath:documentsDirectory] filteredArrayUsingPredicate:predicate];
NSLog(#"%#", matchingPaths);
Swift 2.2 pretty simple:
let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true).first! as NSString
let plistPath = paths.stringByAppendingPathComponent("someFile.plist")
You'll have to walk the tree to find the file; there's no equivalent to -pathForResource:ofType that works in the ~/Documents directory.
I'm trying to load a UIImage from the documents directory and set it to a UIImageView as per below:
NSString *pngfile = [[MyUtil getLocalDirectory] stringByAppendingPathComponent:#"school.png"];
NSLog(#"%#", pngfile);
if ([[NSFileManager defaultManager] fileExistsAtPath:pngfile]) {
NSData *imageData = [NSData dataWithContentsOfFile:pngfile];
UIImage *img = [UIImage imageWithData:imageData];
[schoolImage setImage:img];
}
However, whenever I try the above, the image never loads. The image is in Documents/MyAppCustomDirectory/school.png. Is the above correct to load from that directory?
I also tried a few others: UIImage imageWithContentsOfFile, among other ways based on SO responses.
To get the documents directory you should use:
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [documentPaths objectAtIndex:0];
NSString *pngfile = [documentsDir stringByAppendingPathComponent:#"school.png"];
I'm not quite sure if you also need to append the 'MyAppCustomDirectory', but I don't think so.
Swift 4 Solution:
guard let documentsDirectory = try? FileManager.default.url(for: .documentDirectory,
in: .userDomainMask,
appropriateFor:nil,
create:false)
else {
// May never happen
print ("No Document directory Error")
return nil
}
// Construct your Path from device Documents Directory
var imagesDirectory = documentsDirectory
// Only if your images are un a subdirectory named 'images'
imagesDirectory.appendPathComponent("images", isDirectory: true)
// Add your file name to path
imagesDirectory.appendPathComponent("school.png")
// Create your UIImage?
let result = UIImage(contentsOfFile: imagesDirectory.path)
I have this code this code to save an image to the Documents folder.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *savedImagePath = [documentsDirectory stringByAppendingPathComponent:#"savedImage.png"];
UIImage *image = imageView.image; // imageView is my image from camera
NSData *imageData = UIImagePNGRepresentation(image);
[imageData writeToFile:savedImagePath atomically:NO];
I am looking for a way to be able to save multiple images as this one keeps over writing the savedImage.png name.
I do not mind looking for it on google or whatever, but I need to know what it is called, since looking with the wrong keywords really delays the world:-)
Cheers
You need to change the file name that you are appending to the image documentsDirectory path on line three. Each time you'll need to use a different name that isn't already used. NSFileManager has methods to see if a file exists so you can construct a file name and then test if it exists in that location and if so, increment your duplicate count and try the next one.
if num is an integer you define somewhere and keep around so you know the last one you thought you used (and that you've initialized to 1 somewhere).
// your code to get the directory here, as above
NSFileManager *fm = [NSFileManager ...]
do {
savedImagePath = [documentsDirectory stringByAppendingPathComponent:
[NSString stringWithFormat: #"%#-%d.png", #"savedImage", num]];
num += 1; // for next time
if ( ![fm fileExistsAtPath: savedImagePath] )
{
// save your image here using savedImagePath
exit;
}
} while ( //some kind of test for maximum tries/time or whatever )
you'll have to look up the syntax to get an NSFileManager instance and the exact file exists method signature, but that's the gist of it.
If you save file with current dateTime you don't need to worry about same name override problem
-(NSString*)getCurrentDateTimeAsNSString
{
NSDateFormatter *format = [[NSDateFormatter alloc] init];
[format setDateFormat:#"yyyyMMddHHmmss"];
NSDate *now = [NSDate date];
NSString *retStr = [format stringFromDate:now];
[format release];
return retStr;
}
you can create a new file each time to do that.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"YOURiMAGEfILE.IMAGEeXTENSION"];
NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath: path])
{
path = [documentsDirectory stringByAppendingPathComponent: [NSString stringWithFormat: #"YOURiMAGEfILE.IMAGEeXTENSION] ];
}
and then you can perform your above operations on the created file.
Hope it help You Working For me!!
if let image = info[UIImagePickerControllerOriginalImage] as? UIImage
{
let i = Int(arc4random())
let str = String(i).appending(".png")
let fileManager = FileManager.default
let paths = (NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString).appendingPathComponent(str)
print(paths)
let imageData = UIImagePNGRepresentation(image)
fileManager.createFile(atPath: paths as String, contents: imageData, attributes: nil)
}
else{
print("error")
}