Send HTML email with SKPSMTP iOS - ios

I am trying to send an HTML email from my SKPSMTP code in iOS. Right now, I'm just sending plain text, but I'm trying to upgrade that a little. I've included that code below.
I can't find any documentation. How can I upload an HTML file and include that as it's body. Also, there's an image that's being loaded from the same directory as the HTML file, if that makes a difference in the answer. Thanks.
NSMutableString *emailBody = [NSMutableString stringWithFormat:#"Here's your code again, "];
[emailBody appendString:userCode];
SKPSMTPMessage *email = [[SKPSMTPMessage alloc] init];
email.fromEmail = #"me#gmail.com";
NSString *toEmail = [NSString stringWithFormat:#"%#", self.loginInput.text];
email.toEmail = toEmail;
email.relayHost = #"smtp.gmail.com";
email.requiresAuth = YES;
email.login = #"me#gmail.com";
email.pass = #"myPass";
email.subject = #"Your Validation Code";
email.wantsSecure = YES;
email.delegate = self;
NSDictionary *plainPart = [NSDictionary dictionaryWithObjectsAndKeys:#"text/plain",kSKPSMTPPartContentTypeKey,
emailBody,kSKPSMTPPartMessageKey,#"8bit",kSKPSMTPPartContentTransferEncodingKey, nil];
email.parts = [NSArray arrayWithObjects:plainPart, nil];
// Send it!
[email send];

So, here's the answer I came across, just so everyone else can get the benefit of me struggling through:
//Send them an e-mail
NSError* error = nil;
NSString *path = [[NSBundle mainBundle] pathForResource: #"loginEmail" ofType: #"html"];
NSString *result = [NSString stringWithContentsOfFile: path encoding:
NSUTF8StringEncoding error: &error];
NSRegularExpression *regex = [NSRegularExpression
regularExpressionWithPattern:#"<!--INJECT CODE HERE -->"
options:0
error:&error];
NSString *emailBody = [regex stringByReplacingMatchesInString:result options:0 range:NSMakeRange(0, [result length]) withTemplate:code];
NSLog(#"%#", [emailBody class]);
SKPSMTPMessage *email = [[SKPSMTPMessage alloc] init];
email.fromEmail = #"myemail#gmail.com";
NSString *toEmail = [NSString stringWithFormat:#"%#", self.loginInput.text];
email.toEmail = toEmail;
email.relayHost = #"smtp.gmail.com";
email.requiresAuth = YES;
email.login = #"myemail#gmail.com";
email.pass = #"myPass"
email.subject = #"Your Validation Code";
email.wantsSecure = YES;
email.delegate = self;
NSDictionary *htmlPart = [NSDictionary dictionaryWithObjectsAndKeys:#"text/html",kSKPSMTPPartContentTypeKey, emailBody,kSKPSMTPPartMessageKey,#"8bit",kSKPSMTPPartContentTransferEncodingKey, nil];
email.parts = [NSArray arrayWithObjects:htmlPart, nil];
// Send it!
NSLog(#"ABOUT TO SEND");
[email send];
So, I had to write an HTML file, host all my images on tinypic to include in the HTML, write some text to regex switch out my code variable, load in it in here and attach it as the part of my email with key "text/html". This code works, but if anyone has any other suggestions that are helpful, I'm willing to mark them as the right answer!

Related

Bullet points are not recognized in HTML String

I have a string:
NSString *str1 = #"\u2022 You were held in custody for a longer
period of time than may have been necessary.";
I am converting it into an HTML string using this code :
- (NSString *)HTMLString {
NSDictionary * const exportParams = #{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType};
NSAttributedString *attributed = [[NSAttributedString alloc] initWithString:str1];
NSData *htmlData = [attributed dataFromRange:NSMakeRange(0, attributed.length) documentAttributes:exportParams error:nil];
return [[NSString alloc] initWithData:htmlData encoding:NSUTF8StringEncoding];
}
But bullet points are not showing in the HTML string. It's showing a ? instead of bullet point. Please tell me any solution.
Please try below code -
- (NSString *)HTMLString {
NSDictionary * const exportParams = #{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType};
letterString = [letterString stringByReplacingOccurrencesOfString:#"\u2022" withString:#"•"];
NSAttributedString *attributed = [[NSAttributedString alloc] initWithString:letterString];
NSData *htmlData = [attributed dataFromRange:NSMakeRange(0, attributed.length) documentAttributes:exportParams error:nil];
return [[NSString alloc] initWithData:htmlData encoding:NSUTF8StringEncoding];
}

How to show the output from a deb install ios

I'm building a jailbreak app in which it allows deb installs.
I'm stuck on showing the output or install process in another view controller, similar to iFile and Cydia's own installer.
Does anybody know how to get this to show?
What I have so far is a table view, tap file, action sheet pops up asking to install. Pressing install starts the install process and also opens another blank UIView. How would I pass that data to the opened view?
UPDATE 1 as requested:
Code for installing deb and pushing new view controller to display output:
//Deb file extension
NSString *debFileExtension = [fileName pathExtension];
NSLog(#"fileExtension is: %#", externalFileExtension);
NSSet *supportedFileExtensions = [NSSet setWithObjects:#"deb", nil];
if ([supportedFileExtensions containsObject:[debFileExtension lowercaseString]]) {
documentController = nil;
NSString *actionSheetTitle = fileName;
BlockActionSheet *sheet = [BlockActionSheet sheetWithTitle:actionSheetTitle];
[sheet addButtonWithTitle:#"Install" block:^{
NSString *appsyncDebPath = [path stringByAppendingPathComponent:fileName];
NSString *cmdString=[NSString stringWithFormat:#"/usr/bin/dpkg -i %#",appsyncDebPath];
const char *cmdChar=[cmdString UTF8String];
system(cmdChar);
DebViewController * vc = [[DebViewController alloc] init];
[self.navigationController pushViewController:vc animated:YES];
[vc release];
NSLog(#"Install pressed %#", cmdString);
}];
[sheet setDestructiveButtonWithTitle:#"Cancel" block:nil];
[sheet showInView:self.view];
}
From that the DebViewController gets called. The issue is the displaying of the output or log or w/e in the new view.
Would a regular UIView work? Or do I need a specific view to receive it?
UPDATE 2: with suggested NSTask.
NSTask *task1 = [[NSTask alloc] init];
NSPipe *pipe1 = [NSPipe pipe];
[task1 setLaunchPath: #"/usr/bin/dpkg"];
[task1 setArguments: [NSArray arrayWithObjects: #"-i", nil]];
[task1 setStandardOutput: pipe1];
[task1 launch];
NSFileHandle *file = [pipe1 fileHandleForReading];
NSData * data = [file readDataToEndOfFile];
NSString * string = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
NSLog(#"Result: %#", string);
UITextView *txtview = [[UITextView alloc]initWithFrame:CGRectMake(0, 20, self.view.bounds.size.width, self.view.bounds.size.height)];
txtview.text = string;
//some other setup like setting the font for the UITextView...
[txtview sizeToFit];
[self.view addSubview:txtview];
UPDATE 3:
Everything is working!! Minus 1 thing.
NSString *debPath = [path stringByAppendingPathComponent:fileName];
NSTask *task1 = [[NSTask alloc] init];
NSPipe *pipe1 = [NSPipe pipe];
[task1 setLaunchPath: #"/Applications/myapp.app/"];
[task1 setArguments: [NSArray arrayWithObjects: #"/usr/bin/dpkg", #"-i", debPath, nil]];
[task1 setStandardOutput: pipe1];
[task1 launch];
NSFileHandle *file = [pipe1 fileHandleForReading];
NSData * data = [file readDataToEndOfFile];
OutputViewController * debOutput = [[OutputViewController alloc] init];
UINavigationController *vc = [[UINavigationController alloc] initWithRootViewController:debOutput];
[self.navigationController presentViewController:vc animated:YES completion:nil];
debOutput.output = [[NSString alloc] initWithData:data encoding: NSUTF8StringEncoding];
So the provided code above works as it should, and the receiving view controller displays the output.
Only thing is, that it's not displaying the full output of the deb install. almost like its shorting the lines. I have the output set up as follows:
UITextView *l = [[UITextView alloc] initWithFrame:CGRectMake(5, 0, self.view.frame.size.width-5, self.view.frame.size.height)];
l.editable = NO;
l.textAlignment = NSTextAlignmentLeft;
l.font=[UIFont boldSystemFontOfSize:14];
l.textColor = [UIColor whiteColor];
l.backgroundColor = [UIColor colorWithWhite:0.1f alpha:1.0f];
l.text = [NSString stringWithFormat: #"%#", output];
l.textContainer.lineBreakMode = NSLineBreakByWordWrapping;
[l release];
UPDATE 4:
So what I ended up doing was loading some text in the viewDidLoad when the view first showed:
NSString *cmd0 = #"Running Debian Packager";
NSString *cmd1 = #"Executing Command: /usr/bin/dpkg -i";
NSString *cmd2 = #"Preparing - ";
NSString *cmd3 = #"Installing......Please wait...";
l.text = [NSString stringWithFormat:#"%#\n\n%#\n\n%#%#\n\n%#", cmd0, cmd1, cmd2, fileName, cmd3];
l.textContainer.lineBreakMode = NSLineBreakByWordWrapping;
[view addSubview:l];
Then called the deb install process in the viewDidAppear, which replaces the above code with the output:
//NSTask
NSString *debPath = [path stringByAppendingPathComponent:vc.fileName1];
NSTask *task1 = [[[NSTask alloc] init] autorelease];
NSPipe *pipe1 = [NSPipe pipe];
[task1 setLaunchPath: #"/Applications/myapp.app/process"];
[task1 setArguments: [NSArray arrayWithObjects:#"/usr/bin/dpkg", #"-i", debPath, #"2>/tmp/dpkg.log" ,nil]];
[task1 setStandardOutput: pipe1];
[task1 launch];
NSFileHandle *file = [pipe1 fileHandleForReading];
NSData *data = [file readDataToEndOfFile];
NSString *string = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease];
NSString *cmd3 = #"Success";
NSString *cmd4 = #"*If this package requires a respring, please do so above*";
NSString *dependencies = #"*You are seeing this message because this package requires the additional dependencies listed above*";
NSString *closeCydia = #"*If you are seeing this message, Cydia is probably open. Please close, and try to install the package again*";
//DPKG LOG FILE
NSError *error;
NSString *logPath = [NSString stringWithFormat:#"/tmp"];
NSString *dpkgLogFile = [logPath stringByAppendingPathComponent:#"dpkg.log"];
NSString *logContents = [NSString stringWithContentsOfFile:dpkgLogFile encoding:NSUTF8StringEncoding error:&error];
NSString *dependsString = #"dpkg: dependency problems";
NSString *lockString = #"dpkg: status database area is locked by another process";
if ([logContents containsString:lockString]) {
l.text = [NSString stringWithFormat:#"%#\n%#", logContents, closeCydia];
self.navigationController.navigationBar.topItem.rightBarButtonItem = nil;
}else if ([logContents containsString:dependsString]){
l.text = [NSString stringWithFormat:#"%#\n%#\n%#", string, logContents, dependencies];
self.navigationController.navigationBar.topItem.rightBarButtonItem = nil;
}else{
l.text = [NSString stringWithFormat:#"%#\n%#%#\n\n%#", string, logContents, cmd3, cmd4];
}
[view addSubview:l];
Depending on what the deb installs, I customized the output, i.e. If it has depends, or if the process is locked because Cydia is open.
All in all I'm happy with the turnout. Thanks to Nate for the direction to use NSTask, worked like a charm.
The only thing to make it better is to have it print off or readout, similar to how Cydia goes through line by line.
Instead of using the system() command to run the dpkg command line, I would suggest using NSTask to run the command, which makes it easier to capture the output as a NSString. Once you have a string, you can copy it into a text view, or wherever you like.
NSTask is a private API on iOS, but it's public on OS X, so there's lots of documentation available. In order to use it in your project, just find a copy of the NSTask.h header and copy it into your project (and #import it, of course).
Here's an example of using NSTask to capture command line output in a UIApplication.
Or, another one.
If your install process may take a while, and you'd like your UI to be responsive while it's running, it would be a good idea to run the method that performs the task in the background (using GCD, for example), and then write the resulting string to your UIView (text field, etc.) back on the main/UI thread.

Fetching data from SQLite and want to get only the last value of column id

I am fetching data from SQLite and want to get only the last value of column id in XCode.The code is
NSString *selquery = #"select id from watchlists";
if (self.uid != nil) {
self.uid = nil;
}
self.uid = [[NSArray alloc] initWithArray:[self.dbManager loadDataFromDB:selquery]];
NSString *valvar;
valvar = [_uid lastObject];
NSNumber *custval = [_uid valueForKey: #"#lastObject"];
NSString *imgval1 = [NSString stringWithFormat:#"%#_%s",custval,"1"];
NSLog(#"%#", imgval1);
Please tell me how can I get only the value because by using the above code I am getting array with last value of id.
I think this your case, try this it maybe help you
NSArray *temp=[NSArray arrayWithObjects:#"1",#"2",#"3", nil];
NSArray *temp0ne=[[NSArray alloc]initWithArray:temp];
// NSString *tmmp=[temp0ne lastObject];
NSArray *finalStr=[uid lastObject];
NSLog(#"Dictionary is---->%#",[finalStr lastObject]);
Output:
3_1
EDIT
NSArray *temp=[NSArray arrayWithObjects:#"(1)",#"(2)",#"(3)", nil];
NSArray *temp0ne=[[NSArray alloc]initWithArray:temp];
NSString *tmmp=[temp0ne lastObject];
NSString *final=[tmmp stringByReplacingOccurrencesOfString:#"(" withString:#""];
final=[final stringByReplacingOccurrencesOfString:#")" withString:#""];
NSString *imgval1 = [NSString stringWithFormat:#"%#_%s",final,"1"];
NSLog(#"%#", imgval1);
I don't know is this correct way or not try this....otherwise have look this link
I don't fully understand your code structure hehe. Try this:
NSString *selquery = #"select id from watchlists";
if (self.uid != nil) {
self.uid = nil;
}
self.uid = [[NSArray alloc] initWithArray:[self.dbManager loadDataFromDB:selquery]];
NSNumber *custval = [_uid objectAtIndex:[_uid count]-1];
*
NSString *str = [NSString stringWithFormat#"%#",custval];
str = [str stringByReplacingOccurrencesOfString:#"("
withString:#""];
NSString *finalCustval = [NSString stringWithFormat#"%#",str];
finalCustval = [finalCustval stringByReplacingOccurrencesOfString:#")"
withString:#""];
*
NSString *imgval1 = [NSString stringWithFormat:#"%#_%s",finalCustval ,"1"];
NSLog(#"%#", imgval1);
UPDATE
try adding the ones with *.

How to format data for display in a text view

I have a button that shows some part of the URL on a text view, but I would like for this information to be shown in a specific format.
- (IBAction)Accesos:(id)sender {
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:#"URL"]];
NSError* error;
NSDictionary* json = [NSJSONSerialization
JSONObjectWithData:data
options:kNilOptions
error:&error];
NSArray* Response_array = [json objectForKey:#"avenidas"];
for (int i=0; i < Response_array.count; i++){
NSDictionary* item = [Response_array objectAtIndex:i];
NSString* name = [item objectForKey:#"name"];
NSString* state = [item objectForKey:#"state"];
NSString* space = #"\n";
NSString* formattedString = [NSString stringWithFormat:#"%#%#: %#",space, name, state];
txt_webservice_response.text = formattedString; }
}
The information is shown the same as in the URL I would like to display the information like name: state and then the state to be in color depending the type if it is possible.
NSArray* items = [someDictionary objectForKey:#"avenidas"];
NSDictionary* item = [items objectAtIndex:someIndex];
NSString* name = [item objectForKey:#"name"];
NSString* state = [item objectForKey:#"state"];
NSString* formattedString = [NSString stringWithFormat:#"%#:%#", name, state];
(All of this is first-week stuff -- if you don't know it you need to spend more time studying the fundamentals.)
You can create the HTML for the response and show it to webView for coloring

Email attachment sent using SKPSMTPMessage appears in iOS mail client as contact

I have tested the code for sending attachments using this useful library:
Skpsmtpmessage library
The email seems to get sent correctly, and when I view it through hotmail or gmail clients I see the jpeg image. However, when I view this same email through an iOS mail client, the attachment appears as a "contact" and clicking on this gives me the option to save the file as a new contact.
I have tried sending an email with jpeg attachment from hotmail, and when I do this it appears correctly in the iOS client.
Does anyone know whether this is the code or iOS getting it wrong?
//the guts of the message.
SKPSMTPMessage *testMsg = [[SKPSMTPMessage alloc] init];
testMsg.fromEmail = #"aname#gmail.com";
testMsg.toEmail = #"aname#gmail.com";
testMsg.relayHost = #"smtp.gmail.com";
testMsg.requiresAuth = YES;
testMsg.login = #"aname#gmail.com";
testMsg.pass = #"password";
testMsg.subject = #"The message subject";
testMsg.wantsSecure = YES; // smtp.gmail.com doesn't work without TLS!
// Only do this for self-signed certs!
// testMsg.validateSSLChain = NO;
testMsg.delegate = self;
//email contents
NSDate* now = [NSDate date];
NSString * bodyMessage = [NSString stringWithFormat:#"The message body"];
// email image if it exists
NSString *jpgPath = [NSHomeDirectory() stringByAppendingPathComponent:#"Documents/file.jpeg"];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSMutableArray* parts = [[NSMutableArray alloc] init];
// add plain part
NSDictionary *plainPart = [NSDictionary dictionaryWithObjectsAndKeys:#"text/plain",kSKPSMTPPartContentTypeKey,
bodyMessage ,kSKPSMTPPartMessageKey,#"8bit",kSKPSMTPPartContentTransferEncodingKey,nil];
[parts addObject: plainPart];
// add attachments
NSData *attachmentData = [NSData dataWithContentsOfFile:jpgPath];
NSString *directory = #"text/directory;\r\n\tx-unix-mode=0644;\r\n\tname=\"file.jpeg\"";
NSString *attachment = #"attachment;\r\n\tfilename=\"file.jpeg\"";
NSDictionary *image_part = [NSDictionary dictionaryWithObjectsAndKeys:
directory,kSKPSMTPPartContentTypeKey,
attachment,kSKPSMTPPartContentDispositionKey,
[attachmentData encodeBase64ForData],kSKPSMTPPartMessageKey,
#"base64",kSKPSMTPPartContentTransferEncodingKey,nil];
[parts addObject: image_part];
testMsg.parts = parts;
[testMsg send];
Try to change
NSString *directory = #"text/directory;...
to
NSString *directory = #"text/jpeg;...
I hope this works for you!
Steffen

Resources