Forum Archive

Printing...like on real paper (remember that stuff?)... and objc_util

cook

In Editorial there are some nice workflow options for printing HTML and for creating PDF's with HTML.

After some browsing around I found several ways to deal with printing HTML.

I'm wondering if anyone has created anything to do this yet with objc_util in Pythonista.

There are a few approaches that I could see. One via UIKit (seems better). Another via Webkit.
In the UIKit there seems to be a specific formatter for this: UIMarkupTextPrintFormatter.

I tried a little stab at it..but this crashes Pythonista:

from objc_util import *

content = ns('<h1>test</h1>content')
html = ObjCClass('UIMarkupTextPrintFormatter').alloc().initWithMarkupText_(content)
omz

Most UIKit classes need to be used from the main thread.

This doesn't crash:

from objc_util import *

@on_main_thread
def main():
    content = ns('<h1>test</h1>content')
    html = ObjCClass('UIMarkupTextPrintFormatter').alloc().initWithMarkupText_(content)

main()
cook

Okay I'll give it a try later! Thanks!

cook

Okay.... I successfully printed my test page. But this crashes when I run it. Funny.
I know that it's because of the completion handler, and likely the block is not correct somehow. I am not sure how to write that.

I read through this documentation from Apple but how to implement the block doesn't make sense to me yet. (I'm still scratching my head about the last example @omz gave me with EventKit.

So... This crashes when I choose 'print' or 'cancel'. But it does print! Cool!

# coding: utf-8

from objc_util import *

@on_main_thread
def main():
    printContents = ns('<h1>test</h1>This is a test print page.')
    html = ObjCClass('UIMarkupTextPrintFormatter').alloc().initWithMarkupText_(printContents)
    printController = ObjCClass('UIPrintInteractionController').sharedPrintController()
    printController.setPrintFormatter_(html)
    def completion(completed, _error):
        pass
    completionHandler = ObjCBlock(completion, argtypes = [c_bool, c_void_p])
    printController.presentAnimated_completionHandler_(0, completionHandler)

main()
omz

@cook In this case, you should be able to just pass None as the completion handler.

omz

If you actually need the completion block to do something, your code is almost correct, the block is simply missing the first argument, which is a pointer to the UIPrintInteractionController itself, so it should be something like this (not tested):

def completion(_controller, completed, _error):
    pass

completionHandler = ObjCBlock(completion, argtypes=[c_void_p, c_bool, c_void_p])
# ...
cook

Thanks so much @omz !
I don't believe I need any kind of completion handling...so setting to None works great.

I've now been stuck on trying to figure out page orientation. The documentation is here, and I know that I need to do three things basically...

printInfo = ObjcClass('UIPrintInfo').printInfoWithDictionary_(None) 

printInfo.orientation = #here's where we have problems... 
#in Objc it is just printInfo.orientation = UIPrintInfoOrientationLandscape 
#or printInfo.orientation = UIPrintInfoOrientationPortrait
#I know it will default to portrait, but in particular I want to be able to set it to Landscape.

printController.printInfo = printInfo

I believe I need to make some kind of enumeration - seems to me like some kind of dictionary. Maybe I'm wrong on that.

The documentation referenced above gives me this:

typedef enum {
   UIPrintInfoOrientationPortrait,
   UIPrintInfoOrientationLandscape,
} UIPrintInfoOrientation;

A different kind of topic... is there any other documentation about objc_util than what is available in the app? I'm struggling to grasp how to basically convert objc code into python for use with objc_util. Maybe that is because of my lack of knowledge about Objective C (never learned it!), and even python (just started!)...
I really like objc_util in Pythonista and I hope to use it more, but perhaps it's just way out of my league!!

JonB

An enum generally starts at zero, and counts up. It can be replaced with the corresponding integer. In this case, you would use 0 or 1

cook

Yup that did the trick! Thanks @JonB

Thanks a bunch! I think that's all I want to try with this. I saw there's also a way to set margins so I may put that in as well.