Moving a file in Swift - swift

I'm new to Swift and Xcode. Do I need to change how the path is accessed in some way using NSString or NSUrl? Problems with file path notation (file://)?
#IBAction func buttonPressed(sender: AnyObject) {
let filepath1 = "/Applications/Con.app/Contents/Resources/iTunes.icns"
let filepath2 = "~/Desktop/".stringByExpandingTildeInPath
let fileManager = NSFileManager.defaultManager()
var error: NSError?
fileManager.copyItemAtPath(filepath1, toPath: filepath2, error: nil)
button1.title = "Icon changed"
}

You seem to be using an obsolete version of Swift, but your problem is you're not specifying a filename in your destination path. Change "~/Desktop/" to "~/Desktop/iTunes.icns", for instance. copyItemAtPath(_:toPath:) will by default fail if the destination file already exists, and "~/Desktop/" obviously does.

place the error that you defined before the copyItemAtPath in the parameter list and see what the error coming back is. ie-....error:&error) instead of error:nil)
Also add the file name to the destination string.

Related

Integrating ML Model in Xcode's Swift Playgrounds App

So I am using Xcode Swift Playground App. In which I want to add my two MLModels (Validator and Classifier).
At first, I created a dummy xcode project and I copied the Swift Model Class file. But still, I am getting this error in bundle.url
The issue is that you are force-unwrapping a variable (which is not a very good practice).
The force-unwrapping is failing, because there is not a resource with the same name and path that you are attempting to use.
Instead of force-unwrapping, I would suggest something like this:
class var urlofModelInThisBundle : URL f
let bundle = Bundle(for: self)
if let resource = bundle.url(forResource: "XrayValidator2", withExtension:"mlmodelc") {
return resource
}
else {
Print("ERR: attempted to use a resource that was not found")
return nil
}
You can control-click on your resource names, choose "Reveal in finder" to verify the full names of your resources.
EDIT:
To list all files in the bundle run this and please paste the output into your question:
let paths = Bundle.main.paths(forResourcesOfType: "mlmodelc", inDirectory: nil)
print(paths)
If you don't have any results from that, try this:
let paths = Bundle.main.paths(forResourcesOfType: "mlmodel", inDirectory: nil)
print(paths)

Swift 4+: Issues copying a String to Clipboard using NSPasteboard

I had this all working in Swift 3 and earlier but with Swift 4 no matter what variation I use this code will instead output text as a URL. If I put in "This is my sample text" the output after pasting the clipboard will be "This%20is%20my%20sample%20text". I have tried KuTTypeFileURL but that doesn't appear to make any difference either. What am I missing here? I have seen posts and discussions about how Apple is changing Pboards and other issues with sandboxing but I can't seem to figure this out at all.
original code what was working in swift 3 and earlier
private func copyToClipBoard(textToCopy: String) {
let pasteBoard = NSPasteboard.general()
pasteBoard.clearContents()
pasteBoard.setString(textToCopy, forType: NSStringPboardType)
}
This gives an error of
'NSStringPboardType' is unavailable in Swift: use 'PasteboardType.string'
After searching online I came across these posts that describe the same issue and the workaround was to use the kuTTypeUrl as String
Found here stackoverflow.com/questions/44537356/… and here forums.developer.apple.com/thread/79144
When I try it this way it simply outputs as a URL when I just need a String.
#IBOutlet weak var nameTextField: NSTextField!
#IBAction func nameCopy(_ sender: Any) {
copyToClipBoard(textToCopy: nameTextField.stringValue)
}
let NSStringPboardType = NSPasteboard.PasteboardType(kUTTypeURL as String)
private func copyToClipBoard(textToCopy: String) {
let pasteBoard = NSPasteboard.general
pasteBoard.clearContents()
pasteBoard.setString(textToCopy, forType: NSStringPboardType)
}
You are pasting an URL because you created a PasteboardType kUTTypeURL.
The solution is much simpler, there is a predefined string type
private func copyToClipBoard(textToCopy: String) {
let pasteBoard = NSPasteboard.general
pasteBoard.clearContents()
pasteBoard.setString(textToCopy, forType: .string)
}
The note in the documentation
Apps that adopt App Sandbox cannot access files identified using the string pasteboard type. Instead, use an NSURL object, a bookmark, or a filename pasteboard type.
is related to files (aka string paths), not to regular strings
I just ran into a similar issue. My code looked like this:
NSPasteboard.general.setString("Hello World", forType: .string)
Unfortunately, this didn't work. But I figured there is a bug that if you don't store the NSPasteboard.general into a variable, the object created as part of the general computed property gets deinitialized before the setString change is propagated to the system.
So if you tried doing this in one line like me, just split it up to two instead, which worked for me:
let pasteboard = NSPasteboard.general
pasteboard.setString("Hello World", forType: .string)
I reported this bug via Feedback Assistant to Apple (FB9988062).
UPDATE:
Apple answered my bug report, stating that you need to call declareTypes before setting a value, like so:
NSPasteboard.general.declareTypes([.string], owner: nil)

ReactiveKit Bond KVO observe UserDefaults

I was previously using RxSwift and I decided I did not want to use it anymore and was able to convert everything over to Bond which I am much more familiar with. Since the new changes though to Bond v5, I cannot seem to figure out how to observe values in UserDefaults. The following code ends up giving me a fatal error.
userDefaults.reactive
.keyPath(LocationManager.HomeLocationKey, ofType: String.self, context: .immediateOnMain)
.map(self.initLocation(from:))
.bind(to: self.homeLocation)
userDefaults is a reference to UserDefaults.standard and LocationManager.HomeLocationKey is a string. I am providing the initLocation function below as I know it will be asked for. Below that function I will post the error that I am receiving after the app starts up.
func initLocation(from string: String?) -> Location?
{
guard let dataString = string
else { log.warning("Location data did not exist, returning nil"); return nil }
let json = JSON.parse(dataString)
return Location(from: json)
}
Error:
fatal error: Could not convert nil to String. Maybe `dynamic(keyPath:ofExpectedType:)` method might be of help?): file /Users/sam/Documents/iOS Apps/Drizzle/Pods/Bond/Sources/Shared/NSObject+KVO.swift, line 58
It might not be obvious, but if the observed value can be nil, the ofType argument must be an Optional type. In your case, that would be:
userDefaults.reactive
.keyPath(LocationManager.HomeLocationKey, ofType: Optional<String>.self, context: .immediateOnMain)
...

Swift Impossible Type Inference

I am trying to load a file from my app bundle in Swift 3, and I came across a weird situation with the Swift type inferencing. If I use the following code, I get an error on the third line that says Value of optional type "String?" not unwrapped.
let url = NSURL(fileURLWithPath:Bundle.main.bundlePath)
let url2 = url.appendingPathComponent("foo.txt")
let path:String = url2?.path
To fix the error I unwrap the value on the third line by changing it to:
let path:String = url2?.path!
I now get the error Cannot force unwrap value of a non-optional type 'String'. It seems like Swift can't determine whether the path property is a String or a String?. The autocomplete feature in Xcode says it is a String, but the docs say it is a String?.
The suggested fix by Xcode for the first error was to replace url2?.path with (url2?.path)!, which finally ended up working, but I have no idea why this works and the other ways don't.
let path:String = (url2?.path)!
What is going on? Is this a type inference bug in Swift, or am I missing something super obvious
In Swift, Optional chaining like:
let path:String = url2?.path!
... is interpreted as:
let path:String = url2 != nil ? url2!.path!
: nil
As you see the type of path is non-Optional String, so the expression causes error.
(url2's type is URL?, so the type of property path is String, not String?.)
This is not a direct answer to your question, but I would re-write your code as:
let url = Bundle.main.bundleURL
let url2 = url.appendingPathComponent("foo.txt")
let path:String = url2.path
Shorter, and no worry about Optionals.
You forgot to unwrap url2
appendingPathComponent returns an optional value and you are trying to access it without unwrapping it.
So,
let url2 = url.appendingPathComponent("foo.txt")!
or
guard let url2 = url.appendingPathComponent("foo.txt") else { }
should fix it
EDIT
let path:String? = url2?.path
works also
You can also do this:
let url = Bundle.main.url(forResource: "foo", withExtension: "txt")!
let path:String = url.path

attributesOfItemAtPath returns nil (SWIFT)

I try to get the date (creation/last modified) of a file. The name of it I've already got from NSFileManager. Then I try to access attributes:
var attr : NSDictionary? =
NSFileManager.defaultManager().attributesOfItemAtPath(file.absoluteString!, error: nil)
But I always get nil for "attr". "file" is set:
file NSURL "file:///Users/dirk/Desktop/Bildschirmfoto%202015-02-01%20um%2014.07.41.png" 0x00006000000b3ec0
Any idea? What's wrong?
I got it by myself! :-) The prefix "file://" was the reason. If I remove it, it works.
Just for info.