uiWebView printing a pdf - pdf

Inside of uiwebview, what is a good way print a pdf document?
The pdf is accessible via a url or it can be loaded inside of an iframe.
Using the standard javascript widnow.print() functions will not work.
I am considering using a javascript bridge such as:
- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType {
NSURL *URL = [request URL];
if ([[URL scheme] isEqualToString:#"native"]) {
NSString *urlString = [[request URL] absoluteString];
NSArray *urlParts = [urlString componentsSeparatedByString:#":"];
NSString *cmd = [urlParts objectAtIndex:1];
if ( [cmd isEqualToString:#"printPdf"] ) {
// [self dosomething];
}
}
return YES;
}
At this point I need some sort of xcode function which accept a path to the pdf and send it the airPrinter.
Is this a good approach? I am searching examples of how to print a pdf inside a uiWebView.

As I've earned the tumbleweed badge for no up votes and no responses, I'll post my solution.
This fetches the pdf doc and opens the airPrint dialog--all within a uiWebView.
So if IOS would simply allow the javascript window.print() to function inside of uiWebView, my app would not be setting in the app store waiting for approval and re-release.
Anyway, here's a working solution:
- (void)printInit:(NSString *)parm {
UIPrintInteractionController *controller = [UIPrintInteractionController sharedPrintController];
if(!controller){
NSLog(#"Couldn't get shared UIPrintInteractionController!");
return;
}
NSString *base = #"https://someurl.com/";
NSString *ustr = [base stringByAppendingString:parm];
//NSURL *url = [NSURL fileURLWithPath:ustr];
NSURL *url = [NSURL URLWithString:ustr];
NSData *thePdf = [NSData dataWithContentsOfURL:url];
controller.printingItem = thePdf;
UIPrintInfo *printInfo = [UIPrintInfo printInfo];
printInfo.outputType = UIPrintInfoOutputGeneral;
printInfo.jobName = #"PDFDoc";
controller.printInfo = printInfo;
void (^completionHandler)(UIPrintInteractionController *, BOOL, NSError *) =
^(UIPrintInteractionController *printController, BOOL completed, NSError *error) {
if (!completed && error) {
NSLog(#"FAILED! error = %#",[error localizedDescription]);
}
};
CGRect rect = CGRectMake(310, 5, 100, 5);
[controller presentFromRect:rect inView:self.webView animated:YES completionHandler:completionHandler];
}

Related

Xcode Objective-C: Download a custom font and display it in a UILabel

First of all: Is it possible to download a custom font and display it in a UILabel?
I'm using this code to download a custom font from internet and display it in a UILabel but it does not work.
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize txt_UserName;
- (void)viewDidLoad {
[super viewDidLoad];
// 1
NSString *dataUrl = #"https://dl.dafont.com/dl/?f=stars_fighters";
NSURL *url = [NSURL URLWithString:dataUrl];
// 2
NSURLSessionDataTask *downloadTask = [[NSURLSession sharedSession] dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
// 4: Handle response here
if (error == nil) {
NSLog(#"no error!");
if (data != nil) {
NSLog(#"There is data!");
[self loadFont:data];
}
} else {
NSLog(#"%#", error.localizedDescription);
}
}];
// 3
[downloadTask resume];
}
- (void)loadFont:(NSData *)data
{
NSData *inData = data;
CFErrorRef error;
CGDataProviderRef provider = CGDataProviderCreateWithCFData((CFDataRef)data);
CGFontRef font = CGFontCreateWithDataProvider(provider);
if(!CTFontManagerRegisterGraphicsFont(font, &error)){
CFStringRef errorDescription = CFErrorCopyDescription(error);
NSLog(#"Failed to load font: %#", errorDescription);
// CFRelease(errorDescription);
}
// CFRelease(font);
// CFRelease(provider);
CTFontRef ctFont = CTFontCreateWithGraphicsFont(font, 30, NULL, NULL);
UIFont *uiFont = CFBridgingRelease(ctFont);
dispatch_async(dispatch_get_main_queue(), ^{
[self.txt_UserName setFont:uiFont];
});
[self fontTest];
}
- (void)fontTest
{
NSArray *fontFamilies = [UIFont familyNames];
for (int i = 0; i < [fontFamilies count]; i++) {
NSString *fontFamily = [fontFamilies objectAtIndex:i];
NSArray *fontNames = [UIFont fontNamesForFamilyName:[fontFamilies objectAtIndex:i]];
NSLog (#"%#: %#", fontFamily, fontNames);
}
}
#end
Anyway I'm getting this error: Failed to load font: The operation couldn’t be completed. Invalid argument
At the place of the custom font I get a default iOS font.
Of course it's possible to download a custom font and display it in a UILabel,here is my code that works well:
step 1: Assuming the font file has been saved in the sandbox path Documents / StarsFighters.ttf, load the font and get font name(in YOUR_CLASS .m file):
+ (NSString *)loadFontAndReturnFontName {
NSString *imgFilePath = [NSString stringWithFormat:#"%#/Documents/StarsFighters.ttf",NSHomeDirectory()];
NSURL *fontUrl = [NSURL fileURLWithPath:imgFilePath];
CGDataProviderRef fontDataProvider = CGDataProviderCreateWithURL((__bridge CFURLRef)fontUrl);
CGFontRef fontRef = CGFontCreateWithDataProvider(fontDataProvider);
CGDataProviderRelease(fontDataProvider);
CTFontManagerRegisterGraphicsFont(fontRef, NULL);
NSString *fontName = CFBridgingRelease(CGFontCopyPostScriptName(fontRef));
return fontName;
}
step2: use custom font
NSString *fontname = [YOUR_CLASS loadFontAndReturnFontName];
//fontname is #"StarsFighters",best set it to a global variable or save it
YOUR_LABEL.font = [UIFont fontWithName:fontname size:18.0];

Why is this AsyncImageView not loading the image?

I have the following code:
-(void) viewDidAppear:(BOOL)animated {
AsyncImageView *weatherImageView = [[AsyncImageView alloc] initWithFrame:weatherImage.frame];
NSString *myString = #"http://openweathermap.org/img/w/10d.png";
NSString *url = [NSString stringWithString:myString];
NSLog(#"The complete url is %#", url);
[weatherImageView loadImageFromURL:url];
[self.weatherImage addSubview:weatherImageView];
}
The image URL is all fine but the image does not show up when the view appears.
But if I write the following line in the same method
-(void) viewDidAppear: (BOOL) animated {
[self.weatherImage setImage:[UIImage imageNamed:[UIImage imageNamed:"background.png"]]];
}
I see that the image referred by "background.png" appears neat in the ImageView.
Wondering what is wrong with the first code.
loadImageFromURL expects a NSURL. Not a NSString:
AsyncImageView *weatherImageView = [[AsyncImageView alloc] initWithFrame:weatherImage.frame];
NSString *myString = #"http://openweathermap.org/img/w/10d.png";
NSURL *url = [NSURL URLWithString:myString];
NSLog(#"The complete url is %#", url);
[weatherImageView loadImageFromURL:url];

Air Print Action not doing anything unless file type is png

Wrangling with Air Print not doing anything from a button press, im trying to print a file from screen (my first time implementing this)
Ive added the UIPrintInteractionControllerDelegate in .h
.m Hooked up my button which has been checked as working correctly
Button handler code:
NSString *path = [[NSBundle mainBundle] pathForResource:#"mylocalhtmlfile" ofType:#"HTML"];
NSData *dataFromPath = [NSData dataWithContentsOfFile:path];
UIPrintInteractionController *printController = [UIPrintInteractionController sharedPrintController];
if(printController && [UIPrintInteractionController canPrintData:dataFromPath]) {
printController.delegate = self;
UIPrintInfo *printInfo = [UIPrintInfo printInfo];
printInfo.outputType = UIPrintInfoOutputGeneral;
printInfo.jobName = [path lastPathComponent];
printInfo.duplex = UIPrintInfoDuplexLongEdge;
printController.printInfo = printInfo;
printController.showsPageRange = YES;
printController.printingItem = dataFromPath;
void (^completionHandler)(UIPrintInteractionController *, BOOL, NSError *) = ^(UIPrintInteractionController *printController, BOOL completed, NSError *error) {
if (!completed && error) {
NSLog(#"FAILED! due to error in domain %# with error code %u", error.domain, error.code);
}
};
[printController presentAnimated:YES completionHandler:completionHandler];
}
I get no action whatsoever, no presentation of the air print controls or anything unless file type is set to png

Cacheing UIImage as NSData and getting it back

I'm trying to cache images I load from Flickr. If I load the same image, I'm hoping to use the cached version instead. For some reason, when I download an image from the internet, it works, but if I load it from my cache, it displays a blank image. I checked cacheData, and it has the same amount of bits as the image I put in, so it appears loading the file is working.
Here is how I cache images:
+ (void)cachePhoto:(NSData *)photo withKey:(NSString *)key {
if (photo) {
NSArray * urlArray = [fileManager URLsForDirectory:NSCachesDirectory inDomains:NSUserDomainMask];
NSURL * targetDirectory = (NSURL *)[urlArray objectAtIndex:0];
targetDirectory = [targetDirectory URLByAppendingPathComponent:key];
[photo writeToURL:targetDirectory atomically:YES];
[cachedPhotos addObject:key];
NSLog(#"target url %#", targetDirectory);
}
}
+ (NSData *)photoInCache:(NSString *)key {
if ([cachedPhotos containsObject:key]) {
NSString * path = [[cacheDirectory URLByAppendingPathComponent:key] path];
NSLog(#"path: %#", path);
return [fileManager contentsAtPath:path];
} else {
return nil;
}
}
And my code to get it back:
NSData * cacheData = [PhotoCache photoInCache:key];
if (cacheData) {
self.imageView.image = [UIImage imageWithData:cacheData];
[spinner stopAnimating];
NSLog(#"used cached image");
} else {
dispatch_queue_t downloadQueue = dispatch_queue_create("get photo from flickr", NULL);
dispatch_async(downloadQueue, ^{
NSData * imageData = [[NSData alloc] initWithContentsOfURL:url];
dispatch_async(dispatch_get_main_queue(), ^{
[spinner stopAnimating];
self.imageView.image = [UIImage imageWithData:imageData];
[PhotoCache cachePhoto:imageData
withKey:key];
});
});
}
I figured it out - I was loading the image into the imageView in my prepareForSegue, where the ImageView was not yet loaded. I loaded the image in viewDidLoad and it worked. I also had to use UIImagePNGRepresentation, like suggested in the comments.

Is there quick way to check user access using ALAssetsLibrary?

I think this is a really bad way to check user access to the resources.
Is there better way to get user access?
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
// create library
ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *myasset)
{
accessGiven = YES;
return ;
};
void (^assetGroupEnumberatorFailure)(NSError *) = ^(NSError *error) {
accessGiven = NO;
return;
};
// create 2 blocks
NSURL *url = [[NSURL alloc] initWithString:#" "];
[library assetForURL:url resultBlock:resultblock failureBlock:assetGroupEnumberatorFailure];
// use empty url to check acces..
[library release];
iOS 6.0 has better way to do that.
[ALAssetsLibrary authorizationStatus];
Method Description
Authorization Status Enum