I am creating an app that generates a diferent quote everyday. I wanted to give the user the ability to Share with twitter the quote that was given. I was able to get twitter to pop up with the tweet box, but the quote was not showing up. I tried to get that to happen and now, I get a constant error:
Missing argument for parameter for parameter #1 in call
Problem: I would like to be able to get the quote to fill the tweet box as it pops up after the user taps the twitter button
Here's the code:
@IBAction func shareTweet(sender: AnyObject) {
if SLComposeViewController.isAvailableForServiceType(SLServiceTypeTwitter) {
Share(text:Quote).shareTwitter().characters.count{ sheet in self.presentViewController(sheet, animated: true, completion: nil)};
let tweetShare:SLComposeViewController = SLComposeViewController(forServiceType: SLServiceTypeTwitter)
self.presentViewController(tweetShare, animated: true, completion: nil)
} else {
let alert = UIAlertController(title: "Accounts", message: "Please login to a Twitter account to tweet.", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: nil))
self.presentViewController(alert, animated: true, completion: nil)
}
}
Here is the share.swift class:
import Social
struct Share {
let text: String
init(text: String) {
self.text = text
}
typealias ShareSheet = SLComposeViewController
func shareTwitter(count: Int, action: (ShareSheet -> ()), error: (UIAlertController -> ())) { // Returns either tweetSheet or alert view
if (count < 140) {
if (SLComposeViewController.isAvailableForServiceType(SLServiceTypeTwitter)) {
// Tweets Quote
let sheet: SLComposeViewController = SLComposeViewController(forServiceType: SLServiceTypeTwitter)
sheet.setInitialText(text)
action(sheet)
} else {
// Not logged into Twitter
let alert = UIAlertController(title: "Accounts", message: "Please login to a Twitter account to share", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default, handler: nil))
error(alert)
}
} else {
// Character Count is greater then 140
let alert = UIAlertController(title: "Character Count", message: "Sorry this is too long to tweet", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default, handler: nil))
error(alert)
}
}
Edit: Dec '21 Replaced image to omit name on project.
Your shareTwitter(count: action:)
function takes two parameters. You are calling it with no parameters. You are then trying to call trailing closure parameter on characters.count
. I'm assuming that what you mean to do is this:
Share(text:Quote).shareTwitter(Quote.characters.count) { sheet in self.presentViewController(sheet, animated: true, completion: nil)};
I don't think you actually need the count
parameter on your shareTwitter()
function though. The Share
struct already has the text
stored in a property. Why not just use that?
func shareTwitter(action: (ShareSheet -> ()), error: (UIAlertController -> ())) { // Returns either tweetSheet or alert view
if (text.characters.count < 140) {
// Code removed for brevity
} else {
// Code removed for brevity
}
}
Then you can make your function call like this:
Share(text:Quote).shareTwitter() { sheet in self.presentViewController(sheet, animated: true, completion: nil)};
Additionally, you don't seem to be returning another closure in your action
closure. I think you mean to have your closure parameter returning Void
.
On another note, because you are using two closure parameters, one for action
and another for error
, I don't think your code is going to compile even with that change. You would need to do this:
Share(text:Quote).shareTwitter(action: { sheet in
self.presentViewController(sheet, animated: true, completion: nil)
}) { error in
}
When using a closure that may have an error, the best way to do this is to use a Result
monad. It's not hard to implement this for yourself, but you can take a look at antitypical/Result for a library that gives you a Result
monad out of the box.
With both of those changes, your shareTwitter()
function looks like this:
func shareTwitter(action: (Result<ShareSheet, NSError> -> Void)) { // Returns either tweetSheet or alert view
if (text.characters.count < 140) {
// Code removed for brevity
} else {
// Code removed for brevity
}
}
And it is called like this:
Share(text:Quote).shareTwitter() { result in
switch result {
case .Success(let sheet):
self.presentViewController(sheet, animated: true, completion: nil)};
case .Failure(let error):
// Do something with your error
}
}