UIPasteboard: NSString refuses to copy to clipboard

1.7k views Asked by At

I have the following code to shorten a URL using the bit.ly API.

NSString *shortenedURL = [NSString stringWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://api.bit.ly/v3/shorten?login=%@&apikey=%@&longUrl=%@&format=txt", login, key, self.link.text]] encoding:NSUTF8StringEncoding error:nil];

I also have the following code to copy the shortened URL to the pasteboard:

UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
pasteboard.string = shortenedURL;

However, this does not work. In the output log, this is what is displayed:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIPasteboard setString:]: Argument is not an object of type NSString [(null)]'

So if the argument isn't an object, what is it? I tried assuming it was a URL with this:

UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
pasteboard.URL = shortenedURL;

The same type of error is produced, only saying that the argument is not an NSURL object, instead of the previous error saying the argument is not an NSString object.

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIPasteboard setURL:]: Argument is not an object of type NSURL [(null)]'

Anyone know what to do?

2

There are 2 answers

3
l0gg3r On
NSString *shortenedURL = [NSString stringWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://api.bit.ly/v3/shorten?login=%@&apikey=%@&longUrl=%@&format=txt", login, key, self.link.text]] encoding:NSUTF8StringEncoding error:nil];  

is nil, so it's not a good idea to ignore the error.
Instead of that, do

NSError *loadingError = nil
NSString *shortenedURL = [NSString stringWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://api.bit.ly/v3/shorten?login=%@&apikey=%@&longUrl=%@&format=txt", login, key, self.link.text]] encoding:NSUTF8StringEncoding error:&loadingError]; 
if (!shortenURL) {
    NSLog(@"Error loading: %@", loadingError);
    return;
} else {
    NSLog(@"Success loading: %@", shortenedURL); 
}

You should get "Error loading: error message here", and debug the exact problem what happened.

0
ScottyBlades On

Unfortunately the string property on the UIPasteboard object is not actually a direct reference to a string, but an interface with getters and setters for an Objective-C array of the given type you care about.

Swift provides optionals, but unfortunately UIPasteboard is Objective-C under the hood, which doesn't really support optionals well. This is one of those cases.

If you assign nil (null) to the string property, execution will wrap your null in square brackets as an array [(null)] then attempt to add it to empty array of type [NSURL] and because [(null)] does not match the type of [NSURL] you will get:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIPasteboard setURL:]: Argument is not an object of type NSURL [(null)]'

UIPasteboard GitHub doc

unsafe initializer used