28

I'm trying to send an email from my app. But what I want is if user is having Gmail app on his/her phone, then mail should be sent using it. If Gmail app is unavailable then the user should be redirected to Mailbox.

So how can I know if user contains Gmail app and how can I redirect user to it.

Eric Aya
  • 69,473
  • 35
  • 181
  • 253
Ankita Shah
  • 2,178
  • 3
  • 25
  • 42
  • http://stackoverflow.com/a/19281934/2500457 will help – iphondroid Aug 20 '15 at 09:47
  • Does this answer your question? [Is there a URL handler for Gmail for iOS to compose a message?](https://stackoverflow.com/questions/19281933/is-there-a-url-handler-for-gmail-for-ios-to-compose-a-message) – cbowns Sep 18 '20 at 18:08

5 Answers5

42

Setup for iOS9+

As explained here, if you're on iOS9+, don't forget to add googlegmail to LSApplicationQueriesSchemes on your info.plist

my info.plist

Code to open GMail

Then, you can do the same as the accepted answer (below is my swift 2.3 version):

let googleUrlString = "googlegmail:///co?subject=Hello&body=Hi"
if let googleUrl = NSURL(string: googleUrlString) {
    // show alert to choose app
    if UIApplication.sharedApplication().canOpenURL(googleUrl) {
        if #available(iOS 10.0, *) {
          UIApplication.sharedApplication().openURL(googleUrl, options: [:], completionHandler: nil)
        } else {
          UIApplication.sharedApplication().openURL(googleUrl)
        }
    }
}
Community
  • 1
  • 1
ghashi
  • 1,497
  • 1
  • 13
  • 17
  • 3
    iOS 11: it works w/o adding scheme to your own app. Also you can add `to` argument: `"googlegmail:///co?to=support@test.com&subject=Hello&body=Hi"` – silvansky Sep 19 '17 at 14:54
  • 1
    @silvansky, do you know how to pass multiple lines body? I mean, including new line? So, instead of "Hi" it is "Hi!" then "Bye" on the new line. – user2908517 Jan 15 '18 at 11:22
  • How to add a space in body? – Muruganandham K Jul 04 '18 at 03:30
  • 1
    Have you tried usin `%20` (for space) and `%0D%0A` (for new line) ... it would be something like this: `googlegmail:///co?to=support@test.com&subject=Hello&body=Text%20before%20new%20line.%0D%0AText%20after%20new%20line.` ... check this link: https://stackoverflow.com/questions/15019689/html-insert-line-break-in-email-subject-like-20-is-a-space – ghashi Jul 04 '18 at 04:33
  • 1
    For the `canOpenURL` to work I needed to add `googlegmail` to plist. On iOS 10+. – jzeferino Oct 24 '18 at 12:20
  • `googlegmail:///co?` and `googlegmail://co?`, both are working on iOS 12.1.2 + Gmail 5.0.190113. – Sauvik Dolui Feb 20 '19 at 06:15
  • Source code for the Info.plist `LSApplicationQueriesSchemes googlegmail `. – Ilesh P May 18 '20 at 08:42
  • How do I add a zip file as an attachment? – Dan Selig Mar 10 '21 at 16:29
31

You need to use custom URL Scheme. For gmail application its:

googlegmail://

If you want to compose a message there you can add more parameters to this URL:

co?subject=Example&body=ExampleBody

You can determinate if any kind of application is installed using this code (just replace customURL obviously for an other apps):

NSString *customURL = @"googlegmail://";

if ([[UIApplication sharedApplication] 
canOpenURL:[NSURL URLWithString:customURL]])
{
  [[UIApplication sharedApplication] openURL:[NSURL URLWithString:customURL]];
}
else
{
  //not installed, show popup for a user or an error
}  
Grzegorz Krukowski
  • 18,081
  • 5
  • 50
  • 71
4

For Swift 3.0+

Notes:

  1. This solution shows how to use spaces or newlines in the arguments to the URL (Gmail may not respect the newlines).
  2. It is NOT necessary to register with LSApplicationQueriesSchemes as long as you don't call canOpenURL(url). Just try and use the completion handler to determine if it succeeded.

    let googleUrlString = "googlegmail:///co?to=\(address.addingPercentEncoding(withAllowedCharacters: .alphanumerics) ?? "")&subject=\(subject.addingPercentEncoding(withAllowedCharacters: .alphanumerics) ?? "")&body=\(buildInfo.addingPercentEncoding(withAllowedCharacters: .alphanumerics) ?? "")"
    
    if let googleUrl = URL(string: googleUrlString) {
        UIApplication.shared.open(googleUrl, options: [:]) {
            success in
            if !success {
                 // Notify user or handle failure as appropriate
            }
        }
    }
    else {
        print("Could not get URL from string")
    }
    
biomiker
  • 3,108
  • 1
  • 29
  • 26
1

I couldn't figure out why this wasn't working for me until I realised I was targetting a info_development.plist instead of the production-file info.plist

If you're like me and happen to have multiple Plists (one for development, one for prod etc) make sure you edit it everywhere. ;-)

Yasper
  • 501
  • 5
  • 23
1

Swift 5

These answers can open gmail but what if the user do not have gmail installed in the device? In that case I have handled opening apple mail/outlook/yahoo/spark. If none of them are present, I am showing an alert.

@IBAction func openmailAction() {
    if let googleUrl = NSURL(string: "googlegmail://") {
        openMail(googleUrl)
    } else if let mailURL = NSURL(string: "message://") {
        openMail(mailURL)
    } else if let outlookURL = NSURL(string: "ms-outlook://") {
        openMail(outlookURL)
    } else if let yahooURL = NSURL(string: "ymail://") {
        openMail(yahooURL)
    } else if let sparkUrl = NSURL(string: "readdle-spark://") {
        openMail(sparkUrl)
    } else {
        // showAlert
    }
}

func openMail(_ url: NSURL) {
    if UIApplication.shared.canOpenURL(url as URL) {
        UIApplication.shared.open(url as URL, options: [:], completionHandler: nil)
    }
}

You might also may have to add this in the plist

<key>LSApplicationQueriesSchemes</key>
<array>
    <string>googlegmail</string>
    <string>ms-outlook</string>
    <string>readdle-spark</string>
    <string>ymail</string>
</array>
Naval Hasan
  • 1,226
  • 1
  • 13
  • 18