how to show image on email body - using sksmtplibrary - ios

I have a html content as my email body. I need show an image on my html body. I have tried attaching the image to email and used the filename in html image tag. But the image is not showing. I have also tried using dataUri, which doesnt work in certain email clients.
This is my code.
NSData * imageData = [[NSDataalloc] initWithContentsOfURL: [NSURLURLWithString: #"http://wf.vanillicon.com/f6f63a5a0d149275772ff1cf22595988_100.png"]];
NSString *strFileName = [NSStringWithFormat:#"MyPicture.png"];
NSString *strFormat = [NSStringWithFormat:#"image/png;\r\n\tx-unix-mode=0644;\r\n\tname=\"%#\"",strFileName];
NSString *strFormat2 = [NSStringWithFormat:#"attachment;\r\n\tfilename=\"%#\"",strFileName];
NSDictionary *vcfPart = [NSDictionarydictionaryWithObjectsAndKeys:strFormat,kSKPSMTPPartContentTypeKey,
strFormat2,kSKPSMTPPartContentDispositionKey,[imageData encodeBase64ForData],kSKPSMTPPartMessageKey,#"base64",kSKPSMTPPartContentTransferEncodingKey,nil];
testMsg.parts = [NSArrayarrayWithObject:vcfPart];
NSDictionary *plainPart = [NSDictionarydictionaryWithObjectsAndKeys:#"text/html",kSKPSMTPPartContentTypeKey,
#"<img src=\"MyPicture.png\" width=\"100px\" height=\"100px\" /><h1>Tui</h1>",kSKPSMTPPartMessageKey,
#"8bit",kSKPSMTPPartContentTransferEncodingKey,nil];
testMsg.parts = [NSArrayarrayWithObjects:plainPart,vcfPart,nil];

find out demo codes of email sending via SMPT from below links
https://code.google.com/p/skpsmtpmessage/source/browse/trunk/SMTPSender/Classes/SMTPSenderAppDelegate.m
or
https://github.com/kailoa/iphone-smtp
or
http://iphonesdksnippets.com/post/2009/04/15/Send-email-with-attachments-on-iPhone.aspx
you may be succeed

Sometimes, when you send an HTML email, and you have an image in a tag in that HTML, the email client on the receiving side won't display the images automatically. You may have to click "Show images" on the email.

Related

Create custom metaData on a PDF with iOS

I'm working on a project and I need to create and set my own metadata on a PDF (in order to set a GUID directly into the file).
I am currently able to set classic metadata (e.g creator, keywords...etc) but I can't figure out how to add a custom field.
Here's how I set the metadata:
CFMutableDictionaryRef auxInfo = CFDictionaryCreateMutable(kCFAllocatorDefault, 1, NULL, NULL);
CFDictionaryAddValue(auxInfo, kCGPDFContextCreator, CFSTR("John doo"));
CFDictionaryAddValue(auxInfo, kCGPDFContextAuthor, CFSTR("foo bar"));
CFDictionaryRef auxillaryInformation = CFDictionaryCreateCopy(kCFAllocatorDefault, auxInfo);
CFRelease(auxInfo);
// create a context to draw into
CGContextRef graphicContext = CGPDFContextCreate(PDFDataConsumer, &mediaRect, auxillaryInformation);
CFRelease(auxillaryInformation);
CGDataConsumerRelease(PDFDataConsumer);
I tried to replace the kCGPDFContextThing by a custom name but then when I read the metadata, it doesn't appear at all.
For reading the meta I used that
CGPDFDictionaryRef dict = CGPDFDocumentGetInfo(*pdfDoc);
CGPDFDictionaryGetString(dict, "Creator", &objectValue);
I also try that to add a meta :
NSString* str= #"Hello World";
NSData* data=[str dataUsingEncoding:NSUTF8StringEncoding];
CFDataRef cfdata = CFDataCreate(NULL, [data bytes], [data length]);
CGPDFContextAddDocumentMetadata(graphicContext, cfdata);
But it doesn't seems to work neither, and I'm not sure I understand correctly what's done there.
I am also using PDFNet SDK to help the editing, but it doesn't seems to provide any help about metadata so I'm using quartz.
Any help or advice or anything would be welcome, quite lost and I am not an iOS expert at all !!!
You can do low-level editing of a PDF in PDFNet. Briefly:
Create a new custom entry (on the document's root):
Obj* cust_dict = [[myPDFDoc GetRoot] PutDict:#"_MyCustomData" ];
[cust_dict PutText:#"_myGUID" value:#"123-4567-890"];
Read the custom entry:
Obj* dict = [[myPDFDoc GetRoot] FindObj:#"_MyCustomData"];
DictIterator* itr = [dict Get:#"_myGUID"];
Obj* strObj = [itr Value];
NSString* str = [strObj GetAsPDFText];
NSLog(#"guid is %#", str);
Delete a custom entry:
[[myPDFDoc GetRoot] EraseDictElementWithKey:#"_MyCustomData"];
You could also place metadata on a page's root, or in a more standard location, as outlined here: https://groups.google.com/d/msg/pdfnet-sdk/gtPjLZVbRSQ/Tv5DTb9pRXkJ
For more specific information about adding XMP metadata (as your tag implies you're interested in), try searching XMP on the PDFNet support forum: https://groups.google.com/forum/#!searchin/pdfnet-sdk/XMP
I'm not sure how you would do this with Quartz.
Disclosure: I work for PDFTron, maker of PDFNet.

How to perform Localization using sqlite stored data-iOS App?

In my app i am doing localization to support mutiple languages. For that i am creating .string file and using the following method:
-(NSString*) languageSelectedStringForKey:(NSString*)key;
I am using the Key_value concept for this. its working fine. But My question is:
Let say i have a sqlite database which has all the different languages string which needs to be localized.
For eg: for spanish
"Username" = "nombre de usuario";
"Password" = "contraseƱa";
"Submit" = "presentar";
for french
"Username" = "nom d'utilisateur";
"Password" = "mot de passe";
"Submit" = "soumettre";
all this is insert in a sqlite database.
How can we perform localization with the app that way?
Since you seem to have all strings traduction within one db, you need to have an intermediate data structure that will act as a bridge between the db and your method to localize the string.
You could make use of a dictionary for e.g to store the key string identifier and as a value an array that contain all the languages traduction. You will need to feed this data structure once then.
Note that the recommended way is to use .strings files for localisation so you need to provide us good raison why you can't take this approach.
If those are titles/texts for UIButtons and UILabels use the following syntax in your viewController:
NSString *buttonString = NSLocalizedStringFromTable(#"viewController-title-button-username", #"Localizable", nil);
self.username_label.text = buttonString;
And in your Localizable.strings file you do(you must add localization to your project and set this file to be localized to spanish):
"viewController-title-button-username" = "nombre de usuario";
"tabbar-item1" = "item1 in spanish";
"tabbar-item2" = "item2 in spanish";
"tabbar-item3" = "item3 in spanish";
And the same for the Localizable.strings you have set to be the french:
"viewController-title-button-username" = "nom d'utilisateur";
"tabbar-item1" = "item1 in french";
"tabbar-item2" = "item2 in french";
"tabbar-item3" = "item3 in french";
For your tabbar name, put this in your viewDidLoad for each viewController you have. Just change 1, 2, 3 etc.:
NSString *name = NSLocalizedStringFromTable(#"tabbar-item1", #"Main", nil);
self.title = name;
On the other hand if you are getting either an .xml or retrieving using REST you can do the following:
//Get the name of what you want eg. spanish-data or french-data
NSString *name = NSLocalizedStringFromTable(#"xml-locations-string", #"Main", nil);
//What to add at the end
NSString *append = #".xml";
//Merge strings to what you want to retrieve: spanish-data.xml
NSMutableString *file = [NSMutableString stringWithFormat:#"%#%#", name, append];
//From which URL
NSString *urlString = #"http://www.myDomain.com/ProjectName/";
//Create full URL http://www.myDomain.com/ProjectName/spanish-data.xml
NSString *fileUrl = [NSString stringWithFormat:#"%#%#", urlString, file];
NSURL *url = [NSURL URLWithString:fileUrl];
The data you get back will now be the localized version. And you can use that to set table data or whatever you need.
This is the super simple and therefor not optimized way of doing it. Works for REST as well, you just need to reconstruct to fit your project.

Not able to understand Bing JSON response

My code:
NSString *urlString = [NSString stringWithFormat:#"%#%#%#%#", #"http://api.search.live.net/json.aspx?Appid=am hiding the appid &query=",text,#"&sources=web&web.offset=",offvalue];
NSURL *url = [NSURL URLWithString:urlString];
NSData *data = [NSData dataWithContentsOfURL:url];
The JSON response:
SearchResponse = {
Errors = (
{
Code = 1002;
HelpUrl = "http://msdn.microsoft.com/en-us/library/dd251042.aspx";
Message = "Parameter has invalid value.";
Parameter = "SearchRequest.AppId";
Value = " am hiding the value";
}
);
Query = {
SearchTerms = iphone;
};
Version = "2.2";
};
}
What wrong am I doing here.Can anyone please rectify my query??How to use version 2.2 of the bing API
What is the value of 'text', is this one word or multiple words? You'll need to perform URL_Encode on the parameter 'text' in order to have a valid URL.
See Objective-C and Swift URL encoding
Be sure only to have the URL_Encoding on the text-object and not on the whole URL, otherwise "http://" will be encoded as well, resulting in an invalid URL as well
Eg a space should be %20 , you can verify this by adding a NSLog of the URL
It looks like you entered the wrong AppID judging from.
Parameter = "SearchRequest.AppId";
Make sure that the AppID matches the appID that they assigned your app with the service.
Also (and this sometimes randomly causes issues for me) make sure you put a / at the end of the URL String.

ios - problems after encoding a url string

I have some code to send a url to a remote server. If I do not encode the url, it works perfectly. But if I encode the url, it does not work. So I am pretty sure something is not right with the way I encode the url query string.
Here is my code:
// URL TO BE SUBMITTED.
NSString *urlString =
#"http://www.mydomain.com/test.php?";
// NOW CREATE URL QUERY STRING
NSString *unencoded_query_string =
#"name=%#&user_id=%#&person_name=%#&person_email=%#&privacy=%#";
// PUT PREVIOUSLY SET VALUES INTO THE QUERY STRING
NSString *unencoded_url_with_params =
[NSString stringWithFormat:unencoded_query_string, business , user_id , name , email , privacy_string];
// ENCODE THE QUERY STRING
NSString *escapedString = (__bridge_transfer NSString *)CFURLCreateStringByAddingPercentEscapes(
NULL,
(__bridge CFStringRef)unencoded_url_with_params,
NULL,
(CFStringRef)#"!*'();:#&=+$,/?%#[]",
kCFStringEncodingUTF8);
// NOW APPEND URL TO QUERY STRING
NSString *full_encoded_url_string =
[urlString stringByAppendingString: escapedString];
and then I send this string to the server, and the server does have the correct request file invoked, but isn't able to read the parameters.
Would anyone know what I doing incorrectly here? I am using arc by the way.
Thanks!
I think you probably want to escape each param, not the entire request. Basically you want to escape ampersands, spaces etc that show up in your get variables. Your encoded URL probably looks like this:
http://www.mydomain.com/test.php?name%3DPeter%20Willsey%26user_id%3DUSERID%26person_name%3DPeter%20Willsey%26person_email%3Dpeter%40test.com%26privacy%3D1
and it should look like this:
http://www.mydomain.com/test.php?name=Peter%20Willsey&user_id=25&person_name=Peter%20Willsey&person_email=peter%40test.com&privacy=1

IOS affiliate link shorten with bit.ly not working

I want to use bit.ly to track my itunes affiliate links.
I get affiliate links from http://target.georiot.com.
It works when oppening the direct link (going to itunes).
But when i shorten the affiliate link with bitly, it doesn't go on the same page.
Here is the code for getting the shorten url:
NSString *longURL = link;
NSString *bitlyRequestURLString = [NSString stringWithFormat:#"http://api.bit.ly/shorten?version=2.0.1&format=xml&login=%#&apiKey=%#&longUrl=%#",
#"myappname",
#"myappidentifier",
longURL];
NSURL *bitlyURL = [NSURL URLWithString:bitlyRequestURLString];
// get the short URL from bit.ly
NSError *error;
NSString *response = [NSString stringWithContentsOfURL:bitlyURL encoding:NSUTF8StringEncoding error:&error];
NSString *shortURL = #"";
NSArray *responseParts = [response componentsSeparatedByString:#"<shortUrl>"];
if ([responseParts count] > 1) {
NSString *responsePart = [responseParts objectAtIndex:1];
responseParts = [responsePart componentsSeparatedByString:#"</shortUrl>"];
if ([responseParts count] > 0) {
shortURL = [responseParts objectAtIndex:0];
}
}
Last redirect link goes someting like "http://phobos.apple.com/WebObjects/...."
Any Ideas?
Thanks
You probably need to URL encode your longURL before sending it in the query string to bit.ly
You can use the NSString method stringByAddingPercentEscapesUsingEncoding:
NSString *longURL = [link stringByAddingPercentEscapesUsingEncoding:
NSASCIIStringEncoding];
NSString *bitlyRequestURLString = [NSString stringWithFormat:#"http://api.bit.ly/shorten?version=2.0.1&format=xml&login=%#&apiKey=%#&longUrl=%#",
#"myappname",
#"myappidentifier",
longURL];
I just tried using the bit.ly REST API to create a short url and the URL returned works as expected, see below. It looks like the prior answer suggesting encoding was on target, and standard url encoding (percent encoding, such as http://meyerweb.com/eric/tools/dencoder/) seems to do the trick.
This call (with proper API key):
https://api-ssl.bitly.com/v3/shorten?login=georiot&apiKey=R_MY_API_KEY_HERE&longUrl=http%3A%2F%2Ftarget.georiot.com%2FProxy.ashx%3Fgrid%3D64%26id%3D8i%2FET44NjHw%26offerid%3D146261%26type%3D3%26subid%3D0%26tmpid%3D1826%26RD_PARM1%3Dhttp%3A%2F%2Fitunes.apple.com%2Fus%2Falbum%2Fmetallica%2Fid278116714%3Fuo%3D4%26partnerId%3D30%2F&format=json
Returned:
{ "status_code": 200, "status_txt": "OK", "data": { "long_url": "http://target.georiot.com/Proxy.ashx?grid=64&id=8i/ET44NjHw&offerid=146261&type=3&subid=0&tmpid=1826&RD_PARM1=http://itunes.apple.com/us/album/metallica/id278116714?uo=4&partnerId=30/", "url": "http://bit.ly/zR6uzb", "hash": "zR6uzb", "global_hash": "wFpgG2", "new_hash": 1 } }
The result url works as expected (after removing the escape /'s): http:\bit.ly\zR6uzb
At GeoRiot, we have also recently added a new integrated url shortener which might be of interest to you, however we haven't exposed an API for it quite yet. If you are interested in giving this a shot when we have it available, please let us know. The big benefit here is that the extra redirect between bit.ly and georiot would be removed, speeding up the response time for your users quite a bit.
Anyway, its been a while since the original post, so hopefully you got this figured out. If not let us know and we'll help where we can!

Resources