Detecting the Location your cocoa swift application is running from - cocoa

I'm trying but unable to find out if there is a way using swift to detect the path and name of the .app file that is running
ie if my app is selfupdater.app and its stored in ~username/applications
how can i get this information when selfupdater.app is launched as a string variable in swift

This is called your main bundle folder.
Swift 3 or later
extension URL {
var parentDirectory: URL? {
return (try? resourceValues(forKeys: [.parentDirectoryURLKey]))?.parentDirectory
}
}
let bundleURL = Bundle.main.bundleURL
if let path = bundleURL.parentDirectory?.path {
print(path)
}

Related

Problem with building paths iOS v MacOs in Xamarin Forms app

I have this code:
var myDocuments = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "..", "Shared");
_rootPath = Path.Combine(myDocuments, "VisitsRota.MacOS");
_stylesPath = Path.Combine(_rootPath, "Styles");
_vrrDataFile = Path.Combine(_rootPath, "VisitsRotaData.xml");
// Read in the required data
vrrData = DeserializeFromXml<VisitsRotaData>(_vrrDataFile);
// Build list of month names. Should this property also have a private counterpart?
ListMonths = DateTimeFormatInfo.CurrentInfo.MonthNames.TakeWhile(m => m != String.Empty).ToList();
// Select the current month in the list
ListMonthsSelectedItem = DateTime.Now.ToString("MMMM");
string[] stylesArray = Directory.GetFiles(_stylesPath, "ElderlyInfirm-Schedule-*.xsl")
.Select(file => Path.GetFileName(file)).ToArray<string>();
On the Mac it runs as expect. But on the iOS simulator (which I am new to using) it raises an exception:
System.IO.DirectoryNotFoundException: Could not find a part of the
path
'/Users/xxxxxxx/Library/Developer/CoreSimulator/Devices/B812608B-8131-4386-B189-C646684A8965/data/Containers/Data/Application/EF23B73D-8D38-4F41-995E-FCAE13AE3035/Shared/VisitsRota.MacOS/Styles'.
How should I be able to replicate testing on my iOS build? if I use literal paths instead of Path.Combine etc. I do not have a problem.
I was able to resolve this. My related question / answer about resources helped.
In the comments to this question I was asked:
How are these files being deployed with your app?
That was the key!
I added a constructor to the AppDelegate class:
[Register("AppDelegate")]
public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
{
public AppDelegate()
{
InstallApplicationFiles();
}
The linked Q & A has more info. By getting the app to copy the default files from the resources the issue of paths with the iOS simulator is resolved.

Why is UIDocumentPickerViewController working on iOS, but showing the wrong folder on Mac Catalyst?

The code below works fine on an iPad or iPhone -- saveDocument() (see below) writes to /Users/me/Library/Containers/My-App/Data/Documents, and openDocument() shows me the content of that folder.
On macOS, however, openDocument() shows the Documents folder at the root level of iCloud Drive, not the sandboxed version, which is local to my computer
It's like the documentPickerVC.directoryURL is being ignored. Why is that?
If it helps, the documentURL looks like this:
file:///Users/me/Library/Containers/org.me.My-App/Data/Documents/
Any help would be really, really appreciated!
func saveDocument(){
let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
do {
let puzzleData = try? encoder.encode(puzzle)
print("Saving: \(documentURL)")
let saveableURL = documentURL!.appendingPathComponent("\( .puzzle.date)")
try puzzleData!.write(to: saveableURL)
} catch {
displayError(title: "Error while saving document", message: "There was an error: \(error)")
}
}
// when the user taps on the Open button
#objc func openDocument(){
documentPickerVC = UIDocumentPickerViewController(forOpeningContentTypes: [UTType("public.item")!, UTType("public.data")!], asCopy: true )
documentPickerVC.delegate = self
documentPickerVC.modalPresentationStyle = .formSheet
documentPickerVC.directoryURL = documentURL
self.present(documentPickerVC, animated: true)
}
So, the reason documentURL isn't working is because Apple doesn't support it: specifically, “ This property has no effect in Mac apps built with Mac Catalyst.”

How to select a file in finder in Xamarin?

I am trying to select a file in the Finder, that is not happening the method works well in Obj-C but in Xamarin Finder gets activated but the file is not getting selected.
Whereas if I use Xamarin command to open the file it opens.
Here is the snippet of code that I wrote. Guide me if I am doing something wrong or missing anything?
public override void DidFinishLaunching(NSNotification notification)
{
string fullPath = "/Users/anoopvaidya/Desktop/A/ClientInfoConfig.cs";
NSUrl url = NSUrl.FromString(fullPath);
NSUrl[] urls = { url };
NSWorkspace.SharedWorkspace.OpenFile(fullPath);
//works. But I only want to select in Finder
NSWorkspace.SharedWorkspace.ActivateFileViewer(urls);
//doesn't work
}
Is it related to OS version? I am using 10.13.6.
You need to use a file:// based url:
Example:
using (var url = new NSUrl("file", "localhost", "/Users/Sushi/Desktop/StackOverflow.png"))
{
NSWorkspace.SharedWorkspace.ActivateFileViewer(new NSUrl[] { url });
}

You don't have permission to save file in Mac Mojave

In my macOS app I'm trying to create a directory using the below extension
extension URL {
static func createFolder(folderName: String, folderPath:URL) -> URL? {
let fileManager = FileManager.default
let folderURL = folderPath.appendingPathComponent(folderName)
// If folder URL does not exist, create it
if !fileManager.fileExists(atPath: folderURL.path) {
do {
// Attempt to create folder
// try fileManager.createDirectory(at: folderURL, withIntermediateDirectories: true, attributes: nil)
// try fileManager.createDirectory(atPath: folderURL.path, withIntermediateDirectories: true, attributes: nil)
try fileManager.createDirectory(atPath: folderURL.relativePath, withIntermediateDirectories: true, attributes: nil)
} catch {
print(error.localizedDescription + ":\(folderURL.path)")
return nil
}
}
return folderURL
}
}
When I invoke this call its giving me error
You don’t have permission to save the file “FolderName” in the folder
“SelectedFolder”.:/Users/USERNAME/Workspace/SelectedFolder/FolderName
I have taken look at a similar post and have tried all methods but its still giving me the error, am I missing something here? Any help is appreciated
I am Assuming that your app is sandboxed. So you don't have permission to write folder for location where you are trying to.
If it not intended for Sandboxed you can disable the App Sandbox, it can be turned off by clicking on your project file > target name, selecting the capabilities tab and switching the App Sandbox off.
File System Programming Guide: https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/FileSystemOverview/FileSystemOverview.html
App Sandbox documentation here: https://developer.apple.com/library/archive/documentation/Security/Conceptual/AppSandboxDesignGuide/AppSandboxInDepth/AppSandboxInDepth.html
You can also look security scoped bookmark for persistent resource access.
Documentation here:
https://developer.apple.com/library/archive/documentation/Security/Conceptual/AppSandboxDesignGuide/AppSandboxInDepth/AppSandboxInDepth.html#//apple_ref/doc/uid/TP40011183-CH3-SW16
https://developer.apple.com/library/archive/documentation/Miscellaneous/Reference/EntitlementKeyReference/Chapters/EnablingAppSandbox.html#//apple_ref/doc/uid/TP40011195-CH4-SW18

search file from document directory in ios

I have enabled itune file sharing in my Application.
I have added pdf file in my application directory.
now I want to search that file using my app. and upload it on server.
also if there multiple file and folder I want to show in application. search folder and select specific file and upload it. please suggest best way for doing that.
Appriciate for help.
do
{
let dirPaths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0]
print(dirPaths)
let Pnames = try NSFileManager.defaultManager().contentsOfDirectoryAtPath(dirPaths) as [String]
var ProductImgs:Array<String> = Array<String>()
var ProductNames:Array<String> = Array<String>()
for name in Pnames
{
let fileName:String = name
if fileName.hasSuffix(".pdf")
{
PdfURLs.append(dirPaths.stringByAppendingString("/\(fileName)"))
PdfNames.append(fileName)
print(dirPaths.stringByAppendingString("/\(fileName)"))
}
}
}
catch
{
print(error)
}
If you are fine using third party libraries, it would be great to use Alamofire. It is an HTTP networking library written in Swift.
You can upload the file easily using this one,
let fileURL = NSBundle.mainBundle().URLForResource("Default", withExtension: "png")
Alamofire.upload(.POST, "https://httpbin.org/post", file: fileURL)
For a complete understanding of this library check out this link, https://github.com/Alamofire/Alamofire

Resources