Insert CSS into loaded HTML in UIWebView / WKWebView - ios

I am successfully able to get HTML content and display into my UIWebView.
But want to customize the content by adding an external CSS file. I can only change the size of text and font. I tried every possible solution to make changes but it does not work - it shows no changes.
Below is my code
HTMLNode* body = [parser body];
HTMLNode* mainContentNode = [body findChildWithAttribute:#"id" matchingName:#"main_content" allowPartial:NO];
NSString *pageContent = [NSString stringWithFormat:#"%#%#", cssString, contentHtml];
[webView loadHTMLString:pageContent baseURL:[NSURL URLWithString:#"http://www.example.org"]];
-(void)webViewDidFinishLoad:(UIWebView *)webView1{
int fontSize = 50;
NSString *font = [[NSString alloc] initWithFormat:#"document.getElementsByTagName('body')[0].style.webkitTextSizeAdjust= '%d%%'", fontSize];
NSString *fontString = [[NSString alloc] initWithFormat:#"document.getElementById('body').style.fontFamily=\"helvetica\""];
[webView1 stringByEvaluatingJavaScriptFromString:fontString];
[webView1 stringByEvaluatingJavaScriptFromString:font];
}
Please help me get the css stylesheet in my view.

You can do it like this:
- (void)webViewDidFinishLoad:(UIWebView *)webView {
NSString *cssString = #"body { font-family: Helvetica; font-size: 50px }"; // 1
NSString *javascriptString = #"var style = document.createElement('style'); style.innerHTML = '%#'; document.head.appendChild(style)"; // 2
NSString *javascriptWithCSSString = [NSString stringWithFormat:javascriptString, cssString]; // 3
[webView stringByEvaluatingJavaScriptFromString:javascriptWithCSSString]; // 4
}
What this code does:
// 1 : Define a string that contains all the CSS declarations
// 2 : Define a javascript string that creates a new <style> HTML DOM element and inserts the CSS declarations into it. Actually the inserting is done in the next step, right now there is only the %# placeholder. I did this to prevent the line from becoming too long, but step 2 and 3 could be done together.
// 3 : Combine the 2 strings
// 4 : Execute the javascript in the UIWebView
For this to work, your HTML has to have a <head></head> element.
EDIT:
You can also load the css string from a local css file (named "styles.css" in this case). Just replace step //1 with the following:
NSString *path = [[NSBundle mainBundle] pathForResource:#"styles" ofType:#"css"];
NSString *cssString = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
As another option you can just inject a <link> element to the <head> that loads the CSS file:
- (void)webViewDidFinishLoad:(UIWebView *)webView {
NSString *path = [[NSBundle mainBundle] pathForResource:#"styles" ofType:#"css"];
NSString *javascriptString = #"var link = document.createElement('link'); link.href = '%#'; link.rel = 'stylesheet'; document.head.appendChild(link)";
NSString *javascriptWithPathString = [NSString stringWithFormat:javascriptString, path];
[webView stringByEvaluatingJavaScriptFromString:javascriptWithPathString];
}
This solution works best for large CSS files. Unfortunately it does not work with remote HTML files. You can only use this when you want to insert CSS into HTML that you have downloaded to your app.
UPDATE: WKWebView / Swift 3.x
When you are working with a WKWebView injecting a <link> element does not work because of WKWebView's security settings.
You can still inject the css as a string. Either create the CSS string in your code //1 or put it in a local file //2. Just be aware that with WKWebView you have to do the injection in WKNavigationDelegate's webView(_:didFinish:) method:
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
insertCSSString(into: webView) // 1
// OR
insertContentsOfCSSFile(into: webView) // 2
}
func insertCSSString(into webView: WKWebView) {
let cssString = "body { font-size: 50px; color: #f00 }"
let jsString = "var style = document.createElement('style'); style.innerHTML = '\(cssString)'; document.head.appendChild(style);"
webView.evaluateJavaScript(jsString, completionHandler: nil)
}
func insertContentsOfCSSFile(into webView: WKWebView) {
guard let path = Bundle.main.path(forResource: "styles", ofType: "css") else { return }
let cssString = try! String(contentsOfFile: path).trimmingCharacters(in: .whitespacesAndNewlines)
let jsString = "var style = document.createElement('style'); style.innerHTML = '\(cssString)'; document.head.appendChild(style);"
webView.evaluateJavaScript(jsString, completionHandler: nil)
}

Since UIWebView is deprecated in iOS 12, I'll only answer for WKWebView.
I've implemented CSS loading like it was described in the accepted answer. The problem was that sometimes the transition from HTML with no CSS applied to HTML with CSS was visible.
I think a better approach is to use the WKUserScript to inject the CSS like this:
lazy var webView: WKWebView = {
guard let path = Bundle.main.path(forResource: "style", ofType: "css") else {
return WKWebView()
}
let cssString = try! String(contentsOfFile: path).components(separatedBy: .newlines).joined()
let source = """
var style = document.createElement('style');
style.innerHTML = '\(cssString)';
document.head.appendChild(style);
"""
let userScript = WKUserScript(source: source,
injectionTime: .atDocumentEnd,
forMainFrameOnly: true)
let userContentController = WKUserContentController()
userContentController.addUserScript(userScript)
let configuration = WKWebViewConfiguration()
configuration.userContentController = userContentController
let webView = WKWebView(frame: .zero,
configuration: configuration)
return webView
}()
You can read more about this approach in this blog post.

Instead of applying css with style tag it's better to apply it with the link tag:
func insertContentsOfCSSFile2(into webView: WKWebView) {
guard let path = Bundle.main.path(forResource: "resource", ofType: "css") else { return }
let csFile = "var head = document.getElementsByTagName('head')[0];var link = document.createElement('link'); link.rel = 'stylesheet';link.type = 'text/css';link.href = '\(path)';link.media = 'all';head.appendChild(link);"
webView.evaluateJavaScript(csFile) {(result, error) in
if let error = error {
print(error)
}
}
}
I have tested it.
it is working fine.

You need to add this header before apple style to HTML
let fontName = UIFont.systemFont(ofSize: 17.0).fontName
let htmlContent = """
<header>
<meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no'>
</header>
<style type='text/css'>
img{max-height: 100%; min-height: 100%; height:auto; max-width: 100%; width:auto;margin-bottom:5px;}
p{text-align:left|right|center; line-height: 180%; font-family: '\(fontName)'; font-size: 17px;}
iframe{width:100%; height:250px;}
</style> \(html)
"""
webView.loadHTMLString(htmlContent, baseURL: Bundle.main.bundleURL)

I tried Amer Hukic answer. But did not work just the way it is. I added below code between my html head tags.
<link rel="stylesheet" href="style.css">

See #joern's accepted answer for more complete details. I'm adding this answer because I ran into a weird edge case. My particular use case needed to add styling to a div with a class="dialog". For some reason styling using .dialog and div weren't working though other types of styling were working. In the end I used the following to set the width of the dialog
let width = Int(webView.bounds.width)
let script = "document.getElementsByClassName(\"dialog\")[0].style.width = \"\(width)px\""
webView.evaluateJavaScript(script)

Related

UITextViewL link on xamarin.ios

I have a custom UITextView and need something like this:
Google
By the way, This is my Initialize code on custom class:
void Initialize()
{
Font = UIFont.FromName("Lacuna Regular", 14f);
Editable = false;
DataDetectorTypes = UIDataDetectorType.Link;
Text = "Google";
}
but I don't know how to write the Url where I need to go (in this case, www.google.es).
Thanks in advance!
Via UIDataDetectorType.Links:
uiview.DataDetectorTypes = UIDataDetectorType.Link;
uiview.Text = #"https://www.google.es";
Via NSAttributedStringDocumentAttributes with NSAttributedString:
var urlString = #"Google";
var documentAttributes = new NSAttributedStringDocumentAttributes { DocumentType = NSDocumentType.HTML };
NSError error = null;
var attributedString = new NSAttributedString(NSData.FromString(urlString, NSStringEncoding.UTF8), documentAttributes, ref error);
// Should really check the NSError before applying
uiview.AttributedText = attributedString;

iOS UIWebView totally fails to understand more than one #font-face?

Notice this simple css/html which is being displayed in a local UIWebView:
there's the simulator showing it...
Notice there are two #font-face definitions.
But ... only the second one works. If you swap them around, only the second one works.
So here ...
#font-face {
font-family:'aaa';
src: local('SourceSansPro-Regular'),
url('SourceSansPro-Regular.ttf') format('truetype');
}
#font-face {
font-family:'bbb';
src: local('SourceSansPro-BoldIt'),
url('SourceSansPro-BoldItalic.ttf') format('truetype');
}
only "bbb" works, the other one seems to be "cancelled". Then here ..
#font-face {
font-family:'bbb';
src: local('SourceSansPro-BoldIt'),
url('SourceSansPro-BoldItalic.ttf') format('truetype');
}
#font-face {
font-family:'aaa';
src: local('SourceSansPro-Regular'),
url('SourceSansPro-Regular.ttf') format('truetype');
}
only "aaa" works, the other one seems to be "cancelled".
Here's how to do it in Swift,
// load a simple UIWebView (say, an "about" or "legal" screen)
// base is in template.html
import UIKit
import WebKit
class MinorWebView:UIViewController
{
#IBOutlet var wv:UIWebView!
#IBInspectable var filename:String = "?"
// for example, "about" for "about.html"
...
func makeHtml()
{
print("making html for ... " ,filename)
let ourSize = grid.yourSizeDecisionMechanism
let sizeString = String(format:"%.0f", ourSize)
let p1 = NSBundle.mainBundle().pathForResource("template", ofType: "html")
var html:String = try! NSString(contentsOfFile:p1!, encoding:NSUTF8StringEncoding) as String
let p2 = NSBundle.mainBundle().pathForResource(filename, ofType: "html")
let content:String = try! NSString(contentsOfFile:p2!, encoding:NSUTF8StringEncoding) as String
html = html.stringByReplacingOccurrencesOfString("STUFF", withString:content)
html = html.stringByReplacingOccurrencesOfString("SIZEPOINTS", withString:sizeString)
print("Made html like this ---\n" ,html ,"\n------")
wv.loadHTMLString(html as String, baseURL:nil)
}
}
Simply drag "template.html" and "about.html" in to the project (just as you would with an image); ensure they have target membership.
You have an error in the <style> block: it starts with a <meta> element. This will throw the parser off; apparently it thinks that everything up until the first } is bad and needs to be discarded.
Solution: take the <meta> out of the <style>.

Changing advice language doesn't work

I'm new with Skobbler SDK and learn with the Swift Demo + the well documented tuto (http://developer.skobbler.com/getting-started/ios#sec01)
However, I still can't configure the advice language settings using their instructions ...
Here is my code :
let settings = SKAdvisorSettings()
settings.advisorVoice = "fr"
settings.language = SKAdvisorLanguage.FR
settings.advisorType = SKAdvisorType.AudioFiles
settings.resourcesPath = NSBundle.mainBundle().resourcePath! + "/SKMaps.bundle/AdvisorConfigs/Languages"
The event is define by :
func routingService(routingService: SKRoutingService!, didChangeCurrentAdvice currentAdvice: SKRouteAdvice!, isLastAdvice: Bool) {
NSLog("New advice "+currentAdvice.adviceInstruction)
}
Si I get "in 90 meters turn right " for instance.
By the way, no audio files are played neither
Could you please give me a hand :) ? Thank you in advance
There is a bug in the code that is supposed to "play the audio advice" (in AudioService.m) - the name of the .mp3 file was not correctly built.
I've fixed this by making the following change:
func playAudioFile(audioFileName: String) {
var soundFilePath: String = audioFilesFolderPath + "/" + audioFileName
soundFilePath = soundFilePath + ".mp3"
if !NSFileManager.defaultManager().fileExistsAtPath(soundFilePath)
{
return
}
else
{
audioPlayer = try? AVAudioPlayer(contentsOfURL: NSURL(fileURLWithPath: soundFilePath), fileTypeHint: nil)
audioPlayer.delegate = self
audioPlayer.play()
}
}
This affected only the swift demo and will be fixed in the next update
Ok I found my mistake by replacing :
settings.advisorType = SKAdvisorType.AudioFiles
with
settings.advisorType = SKAdvisorType.TextToSpeech
However I still don't know how to use prerecorded files ... Even with the section "Using prerecorded files in tuto ...
Did you set your settings as the advisorConfigurationSettings of your SKRoutingService?
[SKRoutingService sharedInstance].advisorConfigurationSettings = advisorSettings;
You will also have to set the path for the audio files like this:
NSBundle* advisorResourcesBundle = [NSBundle bundleWithPath:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"SKAdvisorResources.bundle"]];
NSString* soundFilesFolder = [advisorResourcesBundle pathForResource:#"Languages" ofType:#""];
NSString* audioFilesFolderPath = [NSString stringWithFormat:#"%#/%#/sound_files",soundFilesFolder,userLanguageCode];
[AudioService sharedInstance].audioFilesFolderPath = audioFilesFolderPath;
userLanguageCode would be "fr" in your case

WKWebView equivalent for UIWebView's scalesPageToFit

I am updating my iOS app to replace UIWebView with WKWebView. However I don't understand how to achieve the same behavior with WKWebView. With UIWebView I used scalesPageToFit to ensure the web pag was displayed with the same size as the screen size (so as to appear full screen without scrolling).
I found that solution on the web however it does not work :
- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation {
NSString *javascript = #"var meta = document.createElement('meta');meta.setAttribute('name', 'viewport');meta.setAttribute('content', 'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no');document.getElementsByTagName('head')[0].appendChild(meta);";
[webView evaluateJavaScript:javascript completionHandler:nil];
}
you can also try the WKUserScript.
here's my working config:
NSString *jScript = #"var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width'); document.getElementsByTagName('head')[0].appendChild(meta);";
WKUserScript *wkUScript = [[WKUserScript alloc] initWithSource:jScript injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:YES];
WKUserContentController *wkUController = [[WKUserContentController alloc] init];
[wkUController addUserScript:wkUScript];
WKWebViewConfiguration *wkWebConfig = [[WKWebViewConfiguration alloc] init];
wkWebConfig.userContentController = wkUController;
wkWebV = [[WKWebView alloc] initWithFrame:self.view.frame configuration:wkWebConfig];
you can add additional configuration to your WKWebViewConfiguration.
Echo of nferocious76's answer, in swift code:
Swift2.x version
let jscript = "var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width'); document.getElementsByTagName('head')[0].appendChild(meta);"
let userScript = WKUserScript(source: jscript, injectionTime: WKUserScriptInjectionTime.AtDocumentEnd, forMainFrameOnly: true)
let wkUController = WKUserContentController()
wkUController.addUserScript(userScript)
let wkWebConfig = WKWebViewConfiguration()
wkWebConfig.userContentController = wkUController
let youWebView = WKWebView(frame: CGRectZero, configuration: wkWebConfig)
swift3 version
let jscript = "var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width'); document.getElementsByTagName('head')[0].appendChild(meta);"
let userScript = WKUserScript(source: jscript, injectionTime: .atDocumentEnd, forMainFrameOnly: true)
let wkUController = WKUserContentController()
wkUController.addUserScript(userScript)
let wkWebConfig = WKWebViewConfiguration()
wkWebConfig.userContentController = wkUController
let yourWebView = WKWebView(frame: self.view.bounds, configuration: wkWebConfig)
Similar to #nferocious76's but in Swift language
var scriptContent = "var meta = document.createElement('meta');"
scriptContent += "meta.name='viewport';"
scriptContent += "meta.content='width=device-width';"
scriptContent += "document.getElementsByTagName('head')[0].appendChild(meta);"
webView.evaluateJavaScript(scriptContent, completionHandler: nil)
I figured out below soultion. For making the content to fit with the device size.
func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) { for making the content to fit with the device size
let jscript = "var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width'); document.getElementsByTagName('head')[0].appendChild(meta);"
webView.evaluateJavaScript(jscript)
}
C# version, for use in Xamarin Custom Renderer:
string jScript = #"var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width'); document.getElementsByTagName('head')[0].appendChild(meta);";
WKUserScript wkUScript = new WKUserScript((NSString)jScript, WKUserScriptInjectionTime.AtDocumentEnd, true);
WKUserContentController wkUController = new WKUserContentController();
wkUController.AddUserScript(wkUScript);
WKWebViewConfiguration wkWebConfig = new WKWebViewConfiguration();
wkWebConfig.UserContentController = wkUController;
WKWebView webView=new WKWebView(Frame, wkWebConfig);
Adding the below to my HTML script helped me.
<meta name="viewport" content="width=device-width, shrink-to-fit=YES">
It does the same as scalePageToFit in UIWebView.
refer: How to set iOS WkWebview zoom scale
Swift 5 solution:
let javaScript = """
var meta = document.createElement('meta');
meta.setAttribute('name', 'viewport');
meta.setAttribute('content', 'width=device-width');
document.getElementsByTagName('head')[0].appendChild(meta);
"""
webView.evaluateJavaScript(javaScript)
This work for me, I added two attributes in meta: initial-scale=1.0, shrink-to-fit=yes, that help fit text with html have a big image in html.
let jscript = "var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width, initial-scale=1.0, shrink-to-fit=yes'); document.getElementsByTagName('head')[0].appendChild(meta);"
let userScript = WKUserScript(source: jscript, injectionTime: .atDocumentEnd, forMainFrameOnly: true)
let wkUController = WKUserContentController()
wkUController.addUserScript(userScript)
let wkWebConfig = WKWebViewConfiguration()
wkWebConfig.userContentController = wkUController
self.webView = WKWebView(frame: self.view.bounds, configuration: wkWebConfig)
None of this answers were working for me. I was trying to open an Amazon URL for a particular artist. Turns out that Amazon has a mobile responsive URL and a desktop URL. On desktop Safari, I changed to iPhone as user-agent (Develop > User Agent > Safari - iOS 13.1.3 - iPhone) and got the appropriate URL for mobile.
This works for me to fit the image size within width of device for Swift 5
Helpful with dynamic html from server
func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) {
let fontAdjust = "var style = document.createElement('style');style.innerHTML = 'body { -webkit-text-size-adjust: none; }';document.getElementsByTagName('head')[0].appendChild(style);"
let imgAdjust = "var style = document.createElement('style');style.innerHTML = 'img { display: inline;height: auto;max-width: 100%; }';document.getElementsByTagName('head')[0].appendChild(style);"
webKitView.evaluateJavaScript(imgAdjust)
webKitView.evaluateJavaScript(fontAdjust)
webKitView.evaluateJavaScript(imgAdjust)
}
Modern Swift code to use in an extension
extension WKWebView {
func addInitialScaleMetaTag() {
evaluateJavaScript(
"""
var meta = document.createElement("meta");
meta.name = "viewport";
meta.content = "initial-scale=1.0";
document.getElementsByTagName('head')[0].appendChild(meta);
""") { result, error in
// handle error
}
}
}
// 100% work for me
func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) {
//print(#function)
let scriptFontSizeAdjustment = "var style = document.createElement('style');style.innerHTML = 'body { -webkit-text-size-adjust: none; }';document.getElementsByTagName('head')[0].appendChild(style);"
let scriptImgSizeAdjustment = "var style = document.createElement('style');style.innerHTML = 'img { display: inline;height: auto;max-width: 100%; }';document.getElementsByTagName('head')[0].appendChild(style);"
webKitView.evaluateJavaScript(scriptFontSizeAdjustment)
webKitView.evaluateJavaScript(scriptImgSizeAdjustment)
}

How to add a image in email body using MFMailComposeViewController

I am trying to find out the best way to add an image inside the body of the email and not as attachment in ios.
1) Apple has provided a function "addAttachment" and the doc says, to add any image in the content, we should use this function, but I tried that function, and sent an mail, I checked on my browser, it is recieved as an attachment.
2) Secondly, many blogs say to use base64 encoding, but that also wont work, image is sent as a broken one.
So friends, please help me out to find the best available solution to do this.
Regards
Ranjit
Set email format as HTML. This code is woking fine in my app.
MFMailComposeViewController *emailDialog = [[MFMailComposeViewController alloc] init];
NSString *htmlMsg = #"<html><body><p>This is your message</p></body></html>";
NSData *jpegData = UIImageJPEGRepresentation(emailImage, 1.0);
NSString *fileName = #"test";
fileName = [fileName stringByAppendingPathExtension:#"jpeg"];
[emailDialog addAttachmentData:jpegData mimeType:#"image/jpeg" fileName:fileName];
emailDialog setSubject:#"email subject"];
[emailDialog setMessageBody:htmlMsg isHTML:YES];
[self presentModalViewController:emailDialog animated:YES];
[emailDialog release];
Swift 5
import MessageUI
func composeMail() {
let mailComposeVC = MFMailComposeViewController()
mailComposeVC.addAttachmentData(UIImage(named: "emailImage")!.jpegData(compressionQuality: CGFloat(1.0))!, mimeType: "image/jpeg", fileName: "test.jpeg")
mailComposeVC.setSubject("Email Subject")
mailComposeVC.setMessageBody("<html><body><p>This is your message</p></body></html>", isHTML: true)
self.present(mailComposeVC, animated: true, completion: nil)
}
I just went through this recently for Swift.
Function to add photo to email in Swift:
func postEmail() {
var mail:MFMailComposeViewController = MFMailComposeViewController()
mail.mailComposeDelegate = self
mail.setSubject("your subject here")
var image = // your image here
var imageString = returnEmailStringBase64EncodedImage(image)
var emailBody = "<img src='data:image/png;base64,\(imageString)' width='\(image.size.width)' height='\(image.size.height)'>"
mail.setMessageBody(emailBody, isHTML:true)
self.presentViewController(mail, animated: true, completion:nil)
}
Function to return the formatted image:
func returnEmailStringBase64EncodedImage(image:UIImage) -> String {
let imgData:NSData = UIImagePNGRepresentation(image)!;
let dataString = imgData.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0))
return dataString
}
I've found that (at least in my case) a PNG will work in the message composer but NOT when the message is opened / received by the user.
Composer Dandily showing logo PNG image!
Viewer Not so much logo images over here.
(Occasionally there will be a light blue outline where the image should be.)
Using the HTML body string below and the conversion below that seems to do the trick.
Message Body HTML String using JPEG
NSString *body = [NSString stringWithFormat:
#"\
<html>\
<body>\
Check out the App!\
<br>\
Isn't this a terriffic logo?!.\
<br>\
<img src = \"data:image/jpeg;base64,%#\" width = 100 height= 100>\
<br>\
<a href = \"%#\" > CLICK ITTTTTTT! </a>\
</body>\
</html>",
imageString, #"http://www.LOLamazingappLOL.com"];
Convert Image to string with JPEG Data
+ (NSString *)dataStringFromImage:(UIImage *)image
{
NSData *imgData = UIImageJPEGRepresentation(image, 1);
return [imgData base64EncodedStringWithOptions:kNilOptions];
}
Additional Info:
iOS Target = 8.0
iOS Device = 9.1
I am awful with HTML!
Thank you #Richard for the CORRECT answer to this question.
Few things to note:
- Use addAttachmentData
- use setMessageBody and set isHTML:true
you dont have to add manually in your email body. the api will take care of that.
func postEmail() {
var mail:MFMailComposeViewController = MFMailComposeViewController()
mail.mailComposeDelegate = self
mail.setSubject("your subject here")
var image = // your image here
var imageData = UIImageJPEGRepresentation(image, 1)
mail.addAttachmentData(imageData, mimeType:"image/jpeg", fileName:"Your Filename"
var emailBody = "<html><body><p>This is your message</p></body></html>"
mail.setMessageBody(emailBody, isHTML:true)
self.presentViewController(mail, animated: true, completion:nil)}

Resources