Print a PDF that is located online only

Discussion in 'iOS Programming' started by newtoiphonesdk, Sep 15, 2011.

  1. newtoiphonesdk macrumors 6502a

    Joined:
    Jul 30, 2010
    #1
    I'm trying to use this to print a PDF that is online, displayed in a webview. Here is what I have unsuccessfully tried.

    Code:
    -(IBAction)print {
    	NSString *urlString = @"http://www.lagrangecoc.com/meditation.pdf";
    	
    	NSURL *url = [NSURL URLWithString:urlString];
    	
    	NSData *file = [NSData dataWithContentsOfURL:url];
    	
    	NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    	
    	NSString *documentsDirectory = [paths objectAtIndex:0];
    	
    	NSString *pdfPath = [documentsDirectory stringByAppendingPathComponent:@"meditation.pdf"];
    	
    	[file writeToFile:pdfPath atomically:YES];
    	
    	NSString *path = [[NSBundle mainBundle] pathForResource:pdfPath ofType:@"pdf"];
    	NSData *myData = [NSData dataWithContentsOfFile:path];
    	
    	
    	UIPrintInteractionController *pic = [UIPrintInteractionController sharedPrintController];
    	
    	if(pic && [UIPrintInteractionController canPrintData: myData] ) {
    		
    		pic.delegate = self;
    		
    		UIPrintInfo *printInfo = [UIPrintInfo printInfo];
    		printInfo.outputType = UIPrintInfoOutputGeneral;
    		printInfo.jobName = [path lastPathComponent];
    		printInfo.duplex = UIPrintInfoDuplexLongEdge;
    		pic.printInfo = printInfo;
    		pic.showsPageRange = YES;
    		pic.printingItem = myData;
    		
    		void (^completionHandler)(UIPrintInteractionController *, BOOL, NSError *) = ^(UIPrintInteractionController *pic, BOOL completed, NSError *error) {
    			//self.content = nil;
    			if (!completed && error) {
    				NSLog(@"FAILED! due to error in domain %@ with error code %u", error.domain, error.code);
    			} 
    		};
    		
    		[pic presentAnimated:YES completionHandler:completionHandler];
    		
    	}	
    	
    }
    Any suggestions? The PDF is something that changes regularly, so I can't just load it into the app.
     
  2. RonC macrumors regular

    Joined:
    Oct 18, 2007
    Location:
    Chicago-area
    #2
    I have no specific suggestions based on your code (other than it superficially looks about on target), so I offer some general ones based on reading the documentation:
    • Did you implement any of the UIPrintInteractionControllerDelegate methods?
      If not, please do, and drop NSLog statements into them to see what's going on.
    • How does your code compare to some of the sample projects?
     
  3. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #3
    You should be able to debug this kind of code by running it in the debugger and stepping through it line by line. If you get nils for objects that should have a value then you'll have an idea of the problem. This code should be simple to debug that way.

    Is the file downloaded and written to your Documents folder?

    NSBundle pathForResource: will only work for files inside your app bundle. For a file in your Documents folder just use the full path to that file that you determine when writing the file.

    Using dataWithContentsOfURL for a non local file is a bad idea. You need to download files asynchronously. It might work in testing but your app will lock up if the network isn't there.
     
  4. newtoiphonesdk thread starter macrumors 6502a

    Joined:
    Jul 30, 2010
    #4
    It is not saved anywhere in the app currently. All it does right now is display within a webview. I'm getting nils on just about every line of code used. I don't have anything else in code for print except the AirPrint delegate in the header
     
  5. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #5
    What do you think this line does?

    Code:
    [file writeToFile:pdfPath atomically:YES];
     
  6. newtoiphonesdk thread starter macrumors 6502a

    Joined:
    Jul 30, 2010
    #6
    Sorry, wasn't really with it when replying earlier. If it saves as pdfpath (it does as I ran nslog) then what is it about the AirPrint setup that I have done wrong as it never pulls up the print window.
     
  7. ianray macrumors 6502

    Joined:
    Jun 22, 2010
    Location:
    @
    #7
    Consider the path to which you write the PDF, and the path from which you read it. Are they the same? If not, why not?
     
  8. newtoiphonesdk, Sep 16, 2011
    Last edited: Sep 16, 2011

    newtoiphonesdk thread starter macrumors 6502a

    Joined:
    Jul 30, 2010
    #8
    I have no idea. I assumed they would be the same.

    I put in some NSLogs after several lines, and they showed up in the console until it got to this line:
    Code:
    if(pic && [UIPrintInteractionController canPrintData: myData] ) {
    		
    		pic.delegate = self;
    		
    		UIPrintInfo *printInfo = [UIPrintInfo printInfo];
    		printInfo.outputType = UIPrintInfoOutputGeneral;
    		printInfo.jobName = [path lastPathComponent];
    		printInfo.duplex = UIPrintInfoDuplexLongEdge;
    		pic.printInfo = printInfo;
    		pic.showsPageRange = YES;
    		pic.printingItem = myData;
    		
    		void (^completionHandler)(UIPrintInteractionController *, BOOL, NSError *) = ^(UIPrintInteractionController *pic, BOOL completed, NSError *error) {
    			//self.content = nil;
    			if (!completed && error) {
    				NSLog(@"FAILED! due to error in domain %@ with error code %u", error.domain, error.code);
    			} 
    		};
    		
    		[pic presentAnimated:YES completionHandler:completionHandler];
    		
    	}	
    	
    }
    
    I know that means that it didn't return because the controller couldn't print the myData string, but I'm not for sure why it wouldn't.
     
  9. RonC macrumors regular

    Joined:
    Oct 18, 2007
    Location:
    Chicago-area
    #9
    Confirm it in the debugger or with logs. Don't just assume they're the same - you're new at this and things may not work the way you assume them to work...
    Why do you think it might not be able to print myData? What does the documentation for UIPrintInteractionController say about it? Is it nil? Is it the content of a PDF file? Can you confirm that it is what you expect it to be (debugger or logs)?
     
  10. newtoiphonesdk thread starter macrumors 6502a

    Joined:
    Jul 30, 2010
    #10
    Nothing shows nil now in the console or debugger. I click the button for the ibaction code and it saves the file but then just stops once it gets to the if statement for the print controller. The app doesn't crash, it just doesn't execute all like I thought it would.
     
  11. chown33, Sep 16, 2011
    Last edited: Sep 16, 2011

    chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #11
    When execution reaches the point marked A (in red), you have downloaded the PDF data into the NSData named 'file', and written it to disk at the pathname named by the NSString 'pdfPath'.

    Given those two facts, exactly what is the blue-hilited code intended for?
    It looks like complete nonsense. At best, it's some leftover from an earlier attempt.

    First, you're asking for a path in the bundle, of a resource named by pdfPath. But pdfPath is already a complete path.

    Second, you're not checking for the success of either pathForResource or dataWithContentsOfFile. So if there's no such resource, what do you have in myData at the point you want to print? Anything worthwhile? Anything at all?

    Third, why would you want this file located in the bundle, even if it existed? Your original post said:
    But what is the blue-hilited code doing? Well, it's loading a file from the app (or trying to).

    Fourth, why are you reading a file again? You already wrote the downloaded data to disk. You still have it in the NSData whose variable name is 'file'. Why not just print the NSData 'file'?


    What is the length of each of the NSData objects?

    What is their content? You can get a subset of the first few bytes of NSData quite easily, put it in another NSData, then NSLog that smaller NSData to see the hex bytes of the data. Does it look like valid PDF data?


    Break down your if statement into two separate parts. Put an NSLog() in each part, so you know exactly what pic is returning from canPrintData:.
     
  12. newtoiphonesdk, Sep 16, 2011
    Last edited: Sep 16, 2011

    newtoiphonesdk thread starter macrumors 6502a

    Joined:
    Jul 30, 2010
    #12
    The PDF is located online, and about once a week it is overwritten with a new PDF, so that the web view in the app can access one URL but have it changed when we need it to without putting in a new update. I think I finally get it and will try it out and get back on results. Thanks.

    Yea, I still had those 2 lines leftover from earlier attempt. Ran it again with simply trying to print the NSData file, and it worked perfectly fine. Simulator attempt ran well, will try on ePrinter later in day when I get home. Thanks for all the help on this.

    Was also wondering if it is something simple to do to print out a current webpage, just by tweaking a few things in this code, or if other groundwork needs to be laid first?
     

Share This Page