Copying HTML using UIPasteBoard and pasting into Gmail - ios

I am trying to find a way to use UIPasteBoard to copy a HTML string into pasteboard, and be able to paste it into different mail clients on iOS.
I tried two accepted answers from StackOverflow: https://stackoverflow.com/a/6566850/1249958 and https://stackoverflow.com/a/21911997/1249958. Those solutions are working on default iOS mail client but they don't make any difference on Gmail.
I know that Gmail accepts HTML input from pasteboard as copying HTML from Safari and pasting that into Gmail app works as expected.

this will put HTML and plain text on the pasteboard and can be pasted into GMail.
UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
NSString *iOSRichContentKey = #"iOS rich content paste pasteboard type";
NSData *iOSRichContent = [iOSRichContentKey dataUsingEncoding:NSUTF8StringEncoding];
NSString *sampleHTML = #"This is <span style='font-weight:bold'>HTML</span>";
NSString *appleWebArchiveKey = #"Apple Web Archive pasteboard type";
NSData *sampleHTMLData = [sampleHTML dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *dict = #{#"WebMainResource": #{#"WebResourceData": sampleHTMLData, #"WebResourceFrameName": #"", #"WebResourceMIMEType": #"text/html", #"WebResourceTextEncodingName": #"UTF-8", #"WebResourceURL": #"about:blank"}};
NSData *appleWebArchive = [NSPropertyListSerialization dataWithPropertyList:dict format:NSPropertyListBinaryFormat_v1_0 options:0 error:nil];
NSString *plainTextKey = #"public.utf8-plain-text";
NSString *plainText = #"this is plain text";
[pasteboard setItems:#[#{iOSRichContentKey : iOSRichContent, appleWebArchiveKey : appleWebArchive, plainTextKey : plainText}]];

Related

Localized String including emoji codes not working

My question is while
NSLocalizedStringFromTableInBundle(#"Sample Text", #"Localizable", [Globals GetLocalizebundle], #"")
is working perfect and I get Localised string from file but
NSLocalizedStringFromTableInBundle(#"Sample Text \U0001F431", #"Localizable", [Globals GetLocalizebundle], #"")
can't get Localised text from bundle.
Any help appreciated.
I solved this by replacing whole unicode code with "surrogates".
For example 😁 has code "1F601" it's surrogates are D83D and DE01. So 😁 should be localised as "\UD83D\UDE01"
Don't use translated text for key, use something like
"sample_text_emoji" = "Sample Text \U0001F431";
in your localized.string file and then use
NSLocalizedStringFromTableInBundle(#"sample_text_emoji", #"Localizable", [Globals GetLocalizebundle], #"")
Documentation clearly states this is a key, so use it as a key, not a text
NSString *NSLocalizedStringFromTableInBundle(NSString *key, NSString *tableName, NSBundle *bundle, NSString *comment)
Actually, below solved my question but I still don't believe it is a proper solution. Anyway here the code resolves emoji characters for NSLocalizedStringFromTableInBundle:
NSString *str = NSLocalizedStringFromTableInBundle(#"Sample Text", #"Localizable", [Globals GetLocalizebundle], #"");
NSString *stringWithEmoji = [str stringByAppendingString:#" \U0001F431"];
NSData *data = [stringWithEmoji dataUsingEncoding:NSNonLossyASCIIStringEncoding];
NSString *valueUnicode = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSData *dataa = [valueUnicode dataUsingEncoding:NSUTF8StringEncoding];
NSString *valueEmoji = [[NSString alloc] initWithData:dataa encoding:NSNonLossyASCIIStringEncoding];
Where base Localized.string includes "Sample Text" = "Sample Text";
The method is to get Localised text from bundle and then add emoji Unicode to string. Then convert it to NSNonLossyASCIIString. This method is working if you are using same emojis for every language.

Paste UIPasteboard contents in other apps

I used the following code to copy some texts to UIPasteboard:
[[UIPasteboard generalPasteboard] setPersistent:YES];
[UIPasteboard generalPasteboard].string = #"Testing";
And I'm able to read the content by:
NSLog(#"Pasteboard String: %#", [UIPasteboard generalPasteboard].string);
// which gives "Testing"
However, I'm unable to retrieve the copied text in any other apps. What is the proper way to copy texts in my App and then paste in other apps?
Using iOS 8.
// Save text
UIPasteboard* board = [UIPasteboard
pasteboardWithName:#"com.company.wtv" create:YES];
board.persistent=YES; [board setValue:#"123456ccc"
forPasteboardType:#"com.company.wtv.sharedValue"];
// Retrive text
UIPasteboard* board = [UIPasteboard pasteboardWithName:#"com.company.wtv" create:YES];
board.persistent=YES;
NSData* result=nil;
NSString*resultStr=nil;
result =[board valueForPasteboardType:#"com.company.wtv.sharedValue"];
resultStr=[[NSString alloc] initWithData:result encoding:NSUTF8StringEncoding];// I got resultStr containing
123456ccc
NSLog(#"key %#",resultStr);

How to convert formatted content of NSTextView to string

I need transfer content of NSTextView from Mac app to iOS app. I'm using XML as transfered file format.
So I need to save content of NSTextView (text, fonts, colors atd.) as a string. Is there any way how to do that?
One way to do this is to archive the NSAttributedString value. Outline sample code typed directly into answer:
NSTextView *myTextView;
NSString *myFilename;
...
[NSKeyedarchiver archiveRootObject:myTextStorage.textStorage
toFile:myFilename];
To read it back:
myTextView.textStorage.attributedString = [NSKeyedUnarchiver unarchiveObjectWithFile:myFilename];
That's all that is needed to create and read back a file. There are matching methods which create an NSData rather than a file, and you can convert an NSData into an NSString or just insert one into an NSDictionary and serialise that as a plist (XML), etc.
Your best bet is probably to store the text as RFTD and load it as such in the other text view via an NSAttributedString.
// Load
NSFileWrapper* filewrapper = [[NSFileWrapper alloc] initWithPath: path];
NSTextAttachment *attachment = [[NSTextAttachment alloc] initWithFileWrapper: filewrapper];
NSAttributedString* origFile = [NSAttributedString attributedStringWithAttachment: attachment];
// Save
NSData *data = [origFile RTFDFromRange: NSMakeRange(0, [origFile length]) documentAttributes: nil];
[[NSFileManager defaultManager] createFileAtPath: path contents: data attributes:nil];

How do a write and read a string value to/from UIPasteboard in iOS?

I have the following test, failing
NSString * expectedValue = #"achilles";
UIPasteboard *pasteboard = [UIPasteboard pasteboardWithName:#"pb1" create:YES];
pasteboard.persistent = YES;
pasteboard.string = expectedValue;
STAssertEqualObjects(expectedValue, [pasteboard string], #"get written value from pasteboard");
[pasteboard setString:expectedValue];
STAssertEqualObjects(expectedValue, [pasteboard string], #"get written value from pasteboard");
Both of the asserts fail,
'achilles' should be equal to '(null)'
Am I incorrectly writing to the pasteboard, reading from the pasteboard, or both?
I assume the problem is the following:
The string property of UIPasteboard is defined as (see the docs)
#property(nonatomic, copy) NSString *string;
This means that if you assign a string to it, it will be copied, i.e. a new object is created. When you read it back and compare it to the original object, the compare must fail.
If you are writing or reading a string from UIPasteBoard you can easily do it by accessing,
[UIPasteboard generalPasteboard].string = #"your string";
NSString *str = [UIPasteboard generalPasteboard].string];
For reading and writing NSString you can use general paste board.
there are two simple ways to write...
//Method 1
NSString * str=#"your String";
UIPasteboard * pasteboard=[UIPasteboard generalPasteboard];
[pasteboard setString:];
//Method 2
NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding];
[pasteboard setData:data forPasteboardType:(NSString *)kUTTypeText];
and you can read NSString as bellow
UIPasteboard * pasteboard=[UIPasteboard generalPasteboard];
//Method 1
NSLog(#"Text =%#",[pasteboard string]);
//Method 2
NSData * data = [pasteboard dataForPasteboardType:(NSString*)kUTTypeText];
NSString * str =[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"str =%#",str);
For more info you can refer this Blog
Your code passed the testing in Unit Testing. You should point out your development environment if you did have trouble in it.
Test Case '-[TestTests testExample]' started.
Test Case '-[TestTests testExample]' passed (0.001 seconds).
Tested in Xcode 5.1.1 with SDK iOS7.1

iOS: How to copy HTML into the cut-paste buffer?

I'm interested in letting my users copy the text they've entered into the cut-and-paste buffer, but I'd like to do that as HTML.
Is such a thing even possible? Or do I need to use a MIME format? (I have no idea.)
Thanks.
The following code will get your HTML out of your app and into Apple's Mail app. The documentation doesn't give you a great deal of help on this, so in part it's a matter of looking at what Apple's apps park on the pasteboard and then reverse engineering that. This solution draws on an earlier stackoverflow post - follow up the links there for more background.
NSLog(#"Place HTML on the pasteboard");
UIPasteboard* pasteboard = [UIPasteboard generalPasteboard];
NSString *htmlType = #"Apple Web Archive pasteboard type";
// example html string
NSString* htmlString = #"<p style=\"color:gray\"> Paragraft<br><em>Less than a word processor, more than plain text</em>";
NSMutableDictionary *resourceDictionary = [NSMutableDictionary dictionary];
[resourceDictionary setObject:[htmlString dataUsingEncoding:NSUTF8StringEncoding] forKey:#"WebResourceData"];
[resourceDictionary setObject:#"" forKey:#"WebResourceFrameName"];
[resourceDictionary setObject:#"text/html" forKey:#"WebResourceMIMEType"];
[resourceDictionary setObject:#"UTF-8" forKey:#"WebResourceTextEncodingName"];
[resourceDictionary setObject:#"about:blank" forKey:#"WebResourceURL"];
NSDictionary *containerDictionary = [NSDictionary dictionaryWithObjectsAndKeys:resourceDictionary, #"WebMainResource", nil];
NSDictionary *htmlItem = [NSDictionary dictionaryWithObjectsAndKeys:containerDictionary,htmlType,nil];
[pasteboard setItems: [NSArray arrayWithObjects: htmlItem, nil]];
// This approach draws on the blog post and comments at:
// http://mcmurrym.wordpress.com/2010/08/13/pasting-simplehtml-into-the-mail-app-ios/
This solution puts both a HTML and a plain text representation into the pasteboard:
#import <MobileCoreServices/MobileCoreServices.h>
NSString *html = #"<h1>Headline</h1>text";
NSData *data = [html dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *dict = #{#"WebMainResource": #{#"WebResourceData": data, #"WebResourceFrameName": #"", #"WebResourceMIMEType": #"text/html", #"WebResourceTextEncodingName": #"UTF-8", #"WebResourceURL": #"about:blank"}};
data = [NSPropertyListSerialization dataWithPropertyList:dict format:NSPropertyListXMLFormat_v1_0 options:0 error:nil];
NSString *archive = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSString *plain = [html stringByReplacingOccurrencesOfRegex:#"<[^>]+>" withString:#""];
[UIPasteboard generalPasteboard].items = #[#{#"Apple Web Archive pasteboard type": archive, (id)kUTTypeUTF8PlainText: plain}];
It uses -stringByReplacingOccurrencesOfRegex: from RegexKitLite to strip the HTML tags.
I absolutely adore this method of creating HTML-based content that you can paste into other HTML-aware apps, like Mail. However, I noticed that the above solution by Matthew Elton only allowed the pasteboard to be pasted onto HTML-aware apps. Trying to paste the exact same content into the Notes app for example, would fail.
I took the tips from this post: https://stackoverflow.com/a/1078471/351810 and can now successfully paste both HTML and plain text versions of the content that I want.
I use w3schools.
I cut and paste my html code over their example code , on any of their many "Try it yourself" tutorials and then use their "run" button.
e.g. https://www.w3schools.com/html/default.asp

Resources