123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483 |
- /*
- Copyright 2013-2016 appPlant UG
-
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
- */
-
- #import "APPEmailComposerImpl.h"
- #import <Cordova/CDVAvailability.h>
- #ifndef __CORDOVA_4_0_0
- #import <Cordova/NSData+Base64.h>
- #endif
- #import <MessageUI/MFMailComposeViewController.h>
- #import <MobileCoreServices/MobileCoreServices.h>
-
- #include "TargetConditionals.h"
-
- /**
- * Implements the interface methods of the plugin.
- */
- @implementation APPEmailComposerImpl
-
- #pragma mark -
- #pragma mark Public
-
- /**
- * Checks if the mail composer is able to send mails and if an app is available
- * to handle the specified scheme.
- *
- * @param scheme
- * An URL scheme, that defaults to 'mailto:
- */
- - (NSArray*) canSendMail:(NSString*)scheme
- {
- bool canSendMail = [MFMailComposeViewController canSendMail];
- bool withScheme = false;
-
- if (![scheme hasSuffix:@":"]) {
- scheme = [scheme stringByAppendingString:@":"];
- }
-
- scheme = [[scheme stringByAppendingString:@"test@test.de"]
- stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
-
- NSURL *url = [[NSURL URLWithString:scheme]
- absoluteURL];
-
- withScheme = [[UIApplication sharedApplication]
- canOpenURL:url];
-
- if (TARGET_IPHONE_SIMULATOR && [scheme hasPrefix:@"mailto:"]) {
- canSendMail = withScheme = true;
- }
-
- NSArray* resultArray = [NSArray arrayWithObjects:@(canSendMail),@(withScheme), nil];
-
- return resultArray;
- }
-
- /**
- * Instantiates an email composer view.
- *
- * @param properties
- * The email properties like subject, body, attachments
- * @param delegateTo
- * The mail composition view controller’s delegate.
- * @return
- * The configured email composer view
- */
- - (MFMailComposeViewController*) mailComposerFromProperties:(NSDictionary*)props
- delegateTo:(id)receiver
- {
- BOOL isHTML = [[props objectForKey:@"isHtml"] boolValue];
-
- MFMailComposeViewController* draft;
-
- draft = [[MFMailComposeViewController alloc] init];
-
- // Subject
- [self setSubject:[props objectForKey:@"subject"] ofDraft:draft];
- // Body (as HTML)
- [self setBody:[props objectForKey:@"body"] ofDraft:draft isHTML:isHTML];
- // Recipients
- [self setToRecipients:[props objectForKey:@"to"] ofDraft:draft];
- // CC Recipients
- [self setCcRecipients:[props objectForKey:@"cc"] ofDraft:draft];
- // BCC Recipients
- [self setBccRecipients:[props objectForKey:@"bcc"] ofDraft:draft];
- // Attachments
- [self setAttachments:[props objectForKey:@"attachments"] ofDraft:draft];
-
- draft.mailComposeDelegate = receiver;
-
- return draft;
- }
-
- /**
- * Creates an mailto-url-sheme.
- *
- * @param properties
- * The email properties like subject, body, attachments
- * @return
- * The configured mailto-sheme
- */
- - (NSURL*) urlFromProperties:(NSDictionary*)props
- {
- NSString* mailto = [props objectForKey:@"app"];
- NSString* query = @"";
-
- BOOL isHTML = [[props objectForKey:@"isHtml"] boolValue];
-
- NSString* subject = [props objectForKey:@"subject"];
- NSString* body = [props objectForKey:@"body"];
- NSArray* to = [props objectForKey:@"to"];
- NSArray* cc = [props objectForKey:@"cc"];
- NSArray* bcc = [props objectForKey:@"bcc"];
-
- NSArray* attachments = [props objectForKey:@"attachments"];
-
- if (![mailto hasSuffix:@":"]) {
- mailto = [mailto stringByAppendingString:@":"];
- }
-
- mailto = [mailto stringByAppendingString:
- [to componentsJoinedByString:@","]];
-
- if (body.length > 0) {
- if (isHTML) {
- body = [[NSAttributedString alloc] initWithData:[body dataUsingEncoding:NSUTF8StringEncoding] options:@{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute: [NSNumber numberWithInt:NSUTF8StringEncoding]} documentAttributes:nil error:nil].string;
- }
- query = [NSString stringWithFormat: @"%@%@body=%@",
- query, query.length > 0? @"&":@"", [body stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
- }
- if (subject.length > 0) {
- query = [NSString stringWithFormat: @"%@%@subject=%@",
- query, query.length > 0? @"&":@"", [subject stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
- }
-
- if (cc.count > 0) {
- query = [NSString stringWithFormat: @"%@%@cc=%@",
- query, query.length > 0? @"&":@"", [cc componentsJoinedByString:@","]];
- }
-
- if (bcc.count > 0) {
- query = [NSString stringWithFormat: @"%@%@bcc=%@",
- query, query.length > 0? @"&":@"", [bcc componentsJoinedByString:@","]];
- }
-
- if (attachments.count > 0) {
- NSLog(@"The 'mailto' URI Scheme (RFC 2368) does not support attachments.");
- }
-
- if (query.length > 0) {
- query = [@"?" stringByAppendingString:query];
- }
-
- mailto = [mailto stringByAppendingString:query];
-
- return [[NSURL URLWithString:mailto] absoluteURL];
- }
-
- #pragma mark -
- #pragma mark Private
-
- /**
- * Sets the subject of the email draft.
- *
- * @param subject
- * The subject of the email.
- * @param draft
- * The email composer view.
- */
- - (void) setSubject:(NSString*)subject
- ofDraft:(MFMailComposeViewController*)draft
- {
- [draft setSubject:subject];
- }
-
- /**
- * Sets the body of the email draft.
- *
- * @param body
- * The body of the email.
- * @param isHTML
- * Indicates if the body is an HTML encoded string.
- * @param draft
- * The email composer view.
- */
- - (void) setBody:(NSString*)body ofDraft:(MFMailComposeViewController*)draft
- isHTML:(BOOL)isHTML
- {
- [draft setMessageBody:body isHTML:isHTML];
- }
-
- /**
- * Sets the recipients of the email draft.
- *
- * @param recipients
- * The recipients of the email.
- * @param draft
- * The email composer view.
- */
- - (void) setToRecipients:(NSArray*)recipients
- ofDraft:(MFMailComposeViewController*)draft
- {
- [draft setToRecipients:recipients];
- }
-
- /**
- * Sets the CC recipients of the email draft.
- *
- * @param ccRecipients
- * The CC recipients of the email.
- * @param draft
- * The email composer view.
- */
- - (void) setCcRecipients:(NSArray*)ccRecipients
- ofDraft:(MFMailComposeViewController*)draft
- {
- [draft setCcRecipients:ccRecipients];
- }
-
- /**
- * Sets the BCC recipients of the email draft.
- *
- * @param bccRecipients
- * The BCC recipients of the email.
- * @param draft
- * The email composer view.
- */
- - (void) setBccRecipients:(NSArray*)bccRecipients
- ofDraft:(MFMailComposeViewController*)draft
- {
- [draft setBccRecipients:bccRecipients];
- }
-
- /**
- * Sets the attachments of the email draft.
- *
- * @param attachments
- * The attachments of the email.
- * @param draft
- * The email composer view.
- */
- - (void) setAttachments:(NSArray*)attatchments
- ofDraft:(MFMailComposeViewController*)draft
- {
- if (attatchments)
- {
- for (NSString* path in attatchments)
- {
- NSData* data = [self getDataForAttachmentPath:path];
-
- NSString* basename = [self getBasenameFromAttachmentPath:path];
- NSString* pathExt = [basename pathExtension];
- NSString* fileName = [basename pathComponents].lastObject;
- NSString* mimeType = [self getMimeTypeFromFileExtension:pathExt];
-
- // Couldn't find mimeType, must be some type of binary data
- if (mimeType == nil) mimeType = @"application/octet-stream";
-
- [draft addAttachmentData:data mimeType:mimeType fileName:fileName];
- }
- }
- }
-
- /**
- * Returns the data for a given (relative) attachment path.
- *
- * @param path
- * An absolute/relative path or the base64 data.
- * @return
- * The data for the attachment.
- */
- - (NSData*) getDataForAttachmentPath:(NSString*)path
- {
- if ([path hasPrefix:@"file:///"])
- {
- return [self dataForAbsolutePath:path];
- }
- else if ([path hasPrefix:@"res:"])
- {
- return [self dataForResource:path];
- }
- else if ([path hasPrefix:@"file://"])
- {
- return [self dataForAsset:path];
- }
- else if ([path hasPrefix:@"base64:"])
- {
- return [self dataFromBase64:path];
- }
-
- NSFileManager* fileManager = [NSFileManager defaultManager];
-
- if (![fileManager fileExistsAtPath:path]){
- NSLog(@"File not found: %@", path);
- }
-
- return [fileManager contentsAtPath:path];
- }
-
- /**
- * Retrieves the data for an absolute attachment path.
- *
- * @param path
- * An absolute file path.
- * @return
- * The data for the attachment.
- */
- - (NSData*) dataForAbsolutePath:(NSString*)path
- {
- NSFileManager* fileManager = [NSFileManager defaultManager];
- NSString* absPath;
-
- absPath = [path stringByReplacingOccurrencesOfString:@"file://"
- withString:@""];
-
- if (![fileManager fileExistsAtPath:absPath]) {
- NSLog(@"File not found: %@", absPath);
- }
-
- NSData* data = [fileManager contentsAtPath:absPath];
-
- return data;
- }
-
- /**
- * Retrieves the data for a resource path.
- *
- * @param path
- * A relative file path.
- * @return
- * The data for the attachment.
- */
- - (NSData*) dataForResource:(NSString*)path
- {
- NSString* imgName = [[path pathComponents].lastObject
- stringByDeletingPathExtension];
-
- #ifdef __CORDOVA_4_0_0
- if ([imgName isEqualToString:@"icon"]) {
- imgName = @"AppIcon60x60@3x";
- }
- #endif
-
- UIImage* img = [UIImage imageNamed:imgName];
-
- if (img == NULL) {
- NSLog(@"File not found: %@", path);
- }
-
- NSData* data = UIImagePNGRepresentation(img);
-
- return data;
- }
-
- /**
- * Retrieves the data for a asset path.
- *
- * @param path
- * A relative www file path.
- * @return
- * The data for the attachment.
- */
- - (NSData*) dataForAsset:(NSString*)path
- {
- NSFileManager* fileManager = [NSFileManager defaultManager];
- NSString* absPath;
-
- NSBundle* mainBundle = [NSBundle mainBundle];
- NSString* bundlePath = [[mainBundle bundlePath]
- stringByAppendingString:@"/"];
-
- absPath = [path stringByReplacingOccurrencesOfString:@"file:/"
- withString:@"www"];
-
- absPath = [bundlePath stringByAppendingString:absPath];
-
- if (![fileManager fileExistsAtPath:absPath]) {
- NSLog(@"File not found: %@", absPath);
- }
-
- NSData* data = [fileManager contentsAtPath:absPath];
-
- return data;
- }
-
- /**
- * Retrieves the data for a base64 encoded string.
- *
- * @param base64String
- * Base64 encoded string.
- * @return
- * The data for the attachment.
- */
- - (NSData*) dataFromBase64:(NSString*)base64String
- {
- NSUInteger length = [base64String length];
- NSRegularExpression *regex;
- NSString *dataString;
-
- regex = [NSRegularExpression regularExpressionWithPattern:@"^base64:[^/]+.."
- options:NSRegularExpressionCaseInsensitive
- error:Nil];
-
- dataString = [regex stringByReplacingMatchesInString:base64String
- options:0
- range:NSMakeRange(0, length)
- withTemplate:@""];
-
- #ifndef __CORDOVA_3_8_0
- NSData* data = [NSData dataFromBase64String:dataString];
- #else
- NSData* data = [[NSData alloc] initWithBase64EncodedString:dataString options:0];
- #endif
-
- return data;
- }
-
- /**
- * Retrieves the mime type from the file extension.
- *
- * @param extension
- * The file's extension.
- * @return
- * The coresponding MIME type.
- */
- - (NSString*) getMimeTypeFromFileExtension:(NSString*)extension
- {
- if (!extension) {
- return nil;
- }
-
- // Get the UTI from the file's extension
- CFStringRef ext = (CFStringRef)CFBridgingRetain(extension);
- CFStringRef type = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, ext, NULL);
-
- ext = NULL;
-
- // Converting UTI to a mime type
- return (NSString*)CFBridgingRelease(UTTypeCopyPreferredTagWithClass(type, kUTTagClassMIMEType));
- }
-
- /**
- * Retrieves the attachments basename.
- *
- * @param path
- * The file path or bas64 data of the attachment.
- * @return
- * The attachments basename.
- */
- - (NSString*) getBasenameFromAttachmentPath:(NSString*)path
- {
- if ([path hasPrefix:@"base64:"])
- {
- NSString* pathWithoutPrefix;
-
- pathWithoutPrefix = [path stringByReplacingOccurrencesOfString:@"base64:"
- withString:@""];
-
- return [pathWithoutPrefix substringToIndex:
- [pathWithoutPrefix rangeOfString:@"//"].location];
- }
-
- return path;
- }
-
- @end
|