UIPrintInteractionController - Limit print copies / Get number of printed copies - objective-c

I'm developing an iPad app that includes the ability to print a document. Some documents require rights management wherein a limited number of copies may be printed and the number of copies printed must be recorded.
I've scoured the UIPrintInteractionController documentation and have found no such capabilities. This question was asked here over a year ago: iOS Printing UI - limit number of copies and at the time this feature was not available - here's hoping it has since changed.
My questions are:
A year later, does cocoa touch still not have the ability to limit number of copies that can be printed?
Is there any way to GET the number of copies printed?
Is one forced to use the UIPrintInteractionController? If I'm unable to set or get copies, then I may be forced to write my own (if at all possible).

Trying to control the number of copies a user can print using UIPrintInteractionController.
I have the same problem and I was walking home and it hit me. Why dont I just create a category for the UIStepper and override its behavior.
I dont use the UIStepper in my app so this wont effect my app, but if you do theres probably a way you can selectively apply this code.
Anyway, you want something like this:
#implementation UIStepper (MJStepper)
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
self.minimumValue = 1;
self.maximumValue = 1;
}
return self;
}
#end
So create a category and include it in the same view which uses the UIPrintInteractionController
Then set the min and max values on init, and BAM. The print modal says 1 copy and has no uistepper. :)
You could set this to any number programmatically or even give the user a fixed range.
I really wish Apple had a full programmatic API for printing.
I am building a Kiosk app and the last thing I want is for the user to be able to print 100 copies of something.
I think the paper type and printer selection is still annoying but I can probably live with that.
Does anyone know if theres a way to control what Paper types your printer supports?
I know theres a delegate callback which I might be able to use to force a specific type of paper so I might try that.
Anyway, hope this helps! :)

Related

AppleScript Syntax error while working around UI elements (Summary Service)

I'm trying to get/set value from Summary Service application using this code
tell application "SummaryService"
activate
delay 0.1
get value of text area 1 of scroll area 1 of window "Summary"
end tell
And whatever I do (get or set) I get this error
Error image
(!) Generally, I'd like to find a way of launching Summary App with text as an argument (I want to add this possibility into my obj-c app). I've googled for some time and what I get is this one. Nevertheless it makes all the work behind scenes, giving to user only result of text transformation and makes to do some amount of unnecessary work, while I just want to launch default app.
Any help will be appreciated!
System Events can get windows, scroll areas and text areas, SummaryService can't.
tell application "SummaryService" to activate
delay 0.1
tell application "System Events"
tell application process "SummaryService"
get value of text area 1 of scroll area 1 of window "Summary"
end tell
end tell
Finally I don't solve my question in the way I previously want, but I found that there're many opensource summerize libs on github, so I use one
Just one moment since I want to use code written in Swift in my Objective-C project is to add
#import <Reductio/Reductio-Swift.h>
To controller where I want to implement desired functionality and call
[Reductio summarizeWithText:textToChange compression:compressionValue completion:^(NSArray<NSString *> * _Nonnull result) {}];
To get result.
PS: I still interested how to open SummaryService programmatically with text I choose.
PS 2: Suddenly I found such function as NSPerformService, which do exactly what I want. So I implement all the needed functionality in this way:
NSString *stringToSetInPb = #"sample text";
NSPasteboard *pb = [NSPasteboard pasteboardWithUniqueName];
[pb declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:nil];
[pb setString:stringToSetInPb forType:NSStringPboardType];
NSPerformService(#"Summarize", pb);
So question officially can be solved!

Identifying objects in IBM RFT

While executing my script in RFT, my script got failed due to the slight position change of a button. (This button's position slightly changes according to the option selected for previous combo box due to the label appearing near the button)
As there are 2 positions for this button in window, one of my script fails while other passes.
Please suggest how to identify this same object in 2 different places in RFT?
If you're alright with not using pre-mapped values and instead work with objects directly in code (which I've personally found to be extremely useful... it's allowed me to do great and wondrous things with RFT :), the following ought to work fine:
private void clickObject(String uniqueIdentifier) {
// Find object
RootTestObject root = RootTestObject.getRootTestObject();
TestObject[] matchingObjs = root.find(atProperty(".id", uniqueIdentifier));
if (matchingObjs.length > 0) {
// Click the object
((GuiTestObject) matchingObjs[0]).click();
}
// Clean-up
unregister(matchingObjs);
}
Feel free to replace ".id" with whatever property is best suited for the situation... since I work primarily with a web application, the ".id" property has worked splendidly for me.
Because the method finds the object anew each time, it'll grab the object's position wherever it's at at the time the method's called. The clean-up will also prevent any weird, horrible, and otherwise unfortunate UnregisteredObjectExceptions from cropping up.
Without looking at your pages I cannot be sure, but I think the buttons are actually two different buttons. Maybe they are generated by javascript, or they are just un-hidden after the option you select in the combobox.
If they are two different buttons (record them both and look at the recognition properties) you can either replace some properties with a regular expression or check wich button is visible/exists and then click it:
if (btn_button1.exists()) {
btn_button1.click();
} else if (btn_button2.exists()) {
btn_button1.click();
}
Here's a more complete tutorial on Object Recognition.
You can increase the tolerance of Rational Performance Tester AssureScript in the properties tab or you could set the description but hide the value. You can also make a custom code that updates the object map to prepare for this change in a java IF structure

Viewing QTMovie duration attributes?

I've probably spent the last 2 weeks searching through Apple Quicktime documentation to resolve what seems like a pretty basic question, but to no avail. Here's the issue...
I've got several short QTMovie files each containing three tracks -- the usual two containing the sound and video, plus an extra video track holding subtitled text images (making two video tracks in all). If I select one of these tracks in Quicktime Pro and export it as an 'Movie To Image Sequence' I might find say, 142 stills spread throughout the duration of the movie. My search method also reports the correct total number of frames.
Now, I've learned that you can take single-frame images, add them to a QTMovie, and set their individual on-screen display times for however long you want using 'attributeForKey:QTMovieDurationAttribute'. But how on earth do I go about accessing that data again? (which essentially just seems like the reverse of this process).
In pseudo-code what I'm trying to do is something like:
{
select video track #2 ...
call up the first image in the sequence ...
access and note its on-screen duration setting ...
call up the second image ...
access and note its duration ...
... repeat until done.
}
I'm not after editing this data or anything -- just finding out how I can get access to individual frames in a video track ... and where the HECK this timing info is hiding inside the bowels of QT.
As a senior citizen I think I'm starting to get too old for this sort of thing and Quicktime is a big, often complex and confusing framework, so if anyone can help me out with some advice or (ideally) just a few lines of sample code here I'd really appreciate it. Thanks in advance :-)
Okay. After several more days of digging and experimentation I finally found the answer to my own question. To get the (next) subtitle image I used:
// access the subtitle track
Track theTrack = [self getVideoSubtitleTrack];
// set flags to find NEXT image (ignoring the current one)...
myFlags = nextTimeStep;
// ... and search forward from current position.
GetTrackNextInterestingTime(theTrack, myFlags, playheadPos, fixed1, &nextInterestingTime, NULL);
This only finds the start of an image object though, and iterating through the track finds the leading edge of each successive image. But I wanted the end time of the current text too.
After getting the start time, I experimented with the seven available flags and found that setting the flag to 'nextTimeTrackEdit' gets the end time.

Printing without an NSView

Currently I'm writing an app for OSX which will eventually need to be ported to iOS.
The data that needs to be printed is being drawn via CoreGraphics into a PDF context - that is working perfectly.
I've been reading the Apple dev documentation on printing in both iOS and OSX, and, ironically, it actually seems printing from iOS will be easier.
On iOS, UIPrintInteractionController's printingItem property can take an NSData object containing PDF data and print that. Looks like it should be fairly straight-forward.
OSX on the other hand, (looks like it) requires using the NSPrintOperation class - but it seems the only way to get data into an instance is via an NSView. (+printOperationWithView: or +printOperationWithView:printInfo:).
Seeing as the content is formatted and paginated already it seems rather pointless to have to re-draw the PDF data to something like an NSView.
Could there possibly be another way of achieving this that I've missed?
This code is by no means complete, but for anyone who comes across this later, this is basically how you can print directly from an NSData stream:
#define kMimeType #"application/pdf"
#define kPaperType #"A4"
- (void)printData:(NSData *)incomingPrintData {
CFArrayRef printerList; //will soon be an array of PMPrinter objects
PMServerCreatePrinterList(kPMServerLocal, &printerList);
PMPrinter myPrinter;
//iterate over printerList and determine which one you want, assign to myPrinter
PMPrintSession printSession;
PMPrintSettings printSettings;
PMCreateSession(&printSession);
PMCreatePrintSettings(&printSettings);
PMSessionDefaultPrintSettings(printSession, printSettings);
CFArrayRef paperList;
PMPrinterGetPaperList(myPrinter, &paperList);
PMPaper usingPaper;
//iterate over paperList and to set usingPaper to the paper desired
PMPageFormat pageFormat;
PMCreatePageFormatWithPMPaper(&pageFormat, usingPaper);
CGDataProviderRef dataProvider = CGDataProviderCreateWithCFData((CFDataRef)incomingPrintData);
PMPrinterPrintWithProvider(myPrinter, printSettings, pageFormat, (CFStringRef)kMimeType, dataProvider);
}
(via Core Printing Reference)
Beware this code lacks memory management so you will need to use the PMRetain() and PMRelease() functions as well as the CoreFoundation memory-management functions as well.
If anyone can tell me how I can get data from the OSX print dialogue into data I can use in this method I'll accept their answer instead of this. That is, without using Carbon functions.

Objective-c -> class method to main file query

Sorry to bug twice so quickly, but since people were so kind in their informative responces, I figured it couldnt hurt to ask another question.
The same program i tried to make it rather swanky and have a main screen which allows you to click on a button which leads to a limited options screen. This lets you switch the music on or off. Or at least it should do.
The music running code is in the main file (game.m), under the following:
//Music
[Settings setMusicEnabled:YES];
music = [SPSound soundWithContentsOfFile:#"music.caf"];
channel = [[music createChannel] retain];
channel.loop = YES;
channel.volume = 0.25;
if([Settings musicEnabled]){
[channel play];
}
I apologize for the strange format, but it is Sparrow framework. basically, the Settings file contains the class methods I am trying to use. If the methods cause YES, the music is on. If it is No, then the music is off.
settings.m
static BOOL isMusicEnabled;
#implementation Settings
+ (BOOL)musicEnabled
{
return isMusicEnabled;
}
+ (void)setMusicEnabled:(BOOL)value
{
isMusicEnabled = value;
NSLog(#"SME? %i", isMusicEnabled);
}
#end
Now, the options file is working and i tested that section. The program is reading that isMusicEnabled is getting a new value, thus musicEnabled is being altered as well, so there should be a change and the music should be switched off.
However, nothing happens. I have tried to use debugger, but I am not very good at it and I dont understand a lot of the information i am given. I do understand that the problem is sending the message from Settings file to the main/Game file.
I would appriciate anyone's help who could enlighten me as to how this could be solved.
I'm not familiar with Sparrow Framework, but let me make a guess anyway.
[channel play]; starts playing the music in background until the channel is asked to stop playing.
Changing the isMusicEnabled does not trigger any code to stop the currently playing music. When you change the value in Settings, you should inform the channel to stop (most probably by somehow accessing the channel and calling [channel stop].
There's another problem - isMusicEnabled is just a variable in memory, your program will not remember its state between restarts. And Settings are usually supposed to be remembered.
To summarize I see two problems: persisting settings between restarts first and informing about change of settings second. To remember settings I suggest you look into NSUserDefaults class. To inform the channel to stop playing you have couple of options - depending on you skills. Easiest is to simply access the channel variable from within the setMusicEnabled and call stop. Another option would be to use notifications, but for a beginner programmer that is more complicated (look for NSNotificationCenter if interested).