timthedevguy / BGHUDAppKit

* BGHUDAPPKIT is no longer under development by me, I hope that the community will keep it alive and going as I no longer have time to dedicate to the project** The missing HUD controls. Please scroll down to read the readme file for an important notice concerning the future of BGHUDAppKit. Note that there are multiple versions available, 10.5+, 10.6.7, and now 10.7. As soon as I learn how I'll make these all one code base if possible.
http://www.binarymethod.com/
312 stars 57 forks source link

Use of private APIs leads to rejection of all applications using BGHUDAppKit from Mac App Store #38

Closed frankrei closed 13 years ago

frankrei commented 13 years ago

Hi,

My application just got rejected for including BGHUDAppKit:

Using private APIs can lead to a poor user experience should these APIs change in the future. The non-public APIs,OBJCIVAR$_NSButtonCell._normalImage and OBJCIVAR$_NSScroller.sFlags, that are included in your application comes from the following private Apple frameworks - AppKit.framework.

I think this will rapidly become a major issue for everyone using the framework, so I thought I'd give you a heads up..

Best regards,

Frank

timthedevguy commented 13 years ago

Frank,

Yeah I just got an email from another user. This may be the death of BGHUDAppKit, unless Apple changed the internals of NSScroller then I know BGHUDScroller will be dead, unfortunately the private API's I used where because of necessity not choice. I am halting development on every other aspect of BGHUDAppkit and creating an AppStore branch to begin experimental development without the private API calls. Please bookmark http://www.binarymethod.com as this is where my blog is and the progress reports will be posted concerning this.

frankrei commented 13 years ago

Hi,

Yes, I've been spending the last few hours trying to find solutions to those two problems as well..

I've overcome the problem for the _normalImage "hack" (it's not fair to call it that since there's apparently no other way around this anyway) at least for my application.

Instead of looking at the _normalImage, I changed the code to invoke [self bezelStyle] which is 0 for radio buttons and 2 for checkboxes. It's possible that somebody might want to use these bevels on other types of buttons, but at least for me this works:

if ([self bezelStyle] == 2 || [self bezelStyle] == 0 ) {

instead of the previous check.

None too elegant and 3 hours ago, I didn't anything at all about NSButtonCell so it might not a be a solution at all.

I experimenting with using [self image] instead of _normalImage, but to no avail:

The situation with NSScroller really does seem desperate.. it looks like it's not really ready to be subclassed.

Perhaps it's possible to find some settings with the "normal" NSScroller look that don't look too bad. Anything that might unblock us in the short term would be useful in any event.

Thanks for looking into this for us.

Best regards,

Frank

timthedevguy commented 13 years ago

Frank,

No problem, I'm working on ButtonCell right now. Back in the early early versions of BGHUDAppKit I worked around the _normalImage issue by requiring the user to set the image to NSSwitch or NSRadioButton in the IB Inspector, then the image accessor worked like it should, only problem was this didn't draw well during design but fine during actual runs. So this may be a solution, not very elegant but it could work as a temporary fix.

NSScroller is my fear, the problem I have is that the flag I access is the flag that determines wether or not the scroller is Horizontal. Somewhere in Apples version they set this flag, when you override the drawing that flag isn't set so I have to set it, if I don't set it then the rectForPart returns only Vertical rects....so kindof a bummer, but I will be experimenting some here later.

frankrei commented 13 years ago

I hope I have understood this correctly and not using the sFlags would be fine in the case of vertical scrollers.

Horizontal scrollers are a bit of a rarity in most situations where you'd be likely to use a HUD style window. I'd suspect that 95% of all existing BGHUDScroller instances are vertical anyway.

In most situations you can get away with replacing horizontal scrolling (which is a pain anyway) with changing the layout of the content.

The only two places where I'd expect to find horizontal scrollers would be for scrolling around graphics and pre-formatted text.

I'd suggest that getting the HUD look for the vertical scrollers to work but use the default NSScroller drawing for the horizontal scrollers would unblock pretty much everybody.

A separate branch for App Store submissions seems pretty inevitable at this stage.. one as-good-as-we-can-make-it and one-ugly-but-complying-with-the-rules version.

I suspect this will be pretty common practice in a few years months time. A great version of your software for your web site and an crippled version for the App Store.. that's progress.

timthedevguy commented 13 years ago

Frank,

Your understanding is correct, without the private API call ALL scroller instances will be drawn vertical. I like your logic concerning the use of Horizontal scrollers, I may take that advice ;)

If you would be so kind, check out the latest AppStore commit. I believe the Check/Radio button problem has been solved. In your app you will have to go to each Check and type "NSSwitch" in the Image box of IB Inspector, and "NSRadioButton" for Radio buttons. This should then allow BGHUDAppKit to resume drawing of these controls, if you can't see the controls anymore don't worry they are still there, once you set those options they should return.

New projects will be able to just drag a Radio/Check button from the IB Palette and have these options set already.

Let me know if it works ok for you, Thanks

timthedevguy commented 13 years ago

Frank!!!

Good news, I'm pretty sure NSScroller is fixed. I removed ALL calls to sFlags, and it worked. Only thing I can think of is that the parent of the NSScroller is what sets the Horizontal flag, when I originally started developing BGHUDAppKit I was using a Standalone NSScroller, so it had nothing to tell it that it was horizonal...only difference I can think of, but please check out the "appstore" branch and see if your project works as expected.

frankrei commented 13 years ago

Excellent!

I've made the changes and everything appears to be working just fine now.

You are a binary God!

Thanks for your help.

apparentsoft commented 13 years ago

Somebody suggested to override the following method:

And remember the passed NSButtonType. Then decide based on this value. This way one doesn't have to fill image names for existing applications.

timthedevguy commented 13 years ago

apparentsoft,

Yeah, I'm an idiot! lol. I had looked at that function and then realized that I couldn't access the value later on, it never even occurred to me to store it myself. D'OH!!

I'm implementing that now...

frankrei commented 13 years ago

I actually tried implementing setButtonType: and do exactly that. For some reason though (I'm ill and it was approaching midnight, not unlike now in fact), the method never seemed to get called.

I decided that nib unarchiving doesn't call the method and gave up, but it's very possible that I missed something, somewhere.

timthedevguy commented 13 years ago

Frank,

I got the same results, but this time I overrode setValue:ForKey: and watched what was happening. Turns out that IB has an internal setting and that the selection box for Button Type doesn't actually bind to the control but instead is stored elsewhere and certain settings are set to make it this control style (just like it says in docs)

So I could possibly cheat and intercept that value, set my internal button type to Check/Radio based off of that.

Just got done running a series of tests on this method and it works perfectly fine. I hope Apple doesn't object to providing my own setValue:ForKey: method, it doesn't appear to be private....

Now Check/Radio buttons are created just by selecting the Bezel type of Check or Radio. In an existing project just toggle from one to the other to set up the change.

tomaz commented 13 years ago

Gee, thanks, just got rejected for this :)

Seems everything is working after updating to latest code, except checkboxes were not drawn in my NSTableColumn (I only use checkbox in one place, and at this point can't confirm this is general problem). I tried all you've written - changing bezel type etc., but it didn't work, column just remained empty in runtime (was properly shown in IB). Also removed ibplugin from IB and re-added new one but the problem still remained (I'm using Release_10.6_10.5_32_64_GC_embed if that makes any difference).

Running in debugger I noticed setButtonType: wasn't sent, so draw method didn't draw properly. The fastest solution was to create IBOutlet BGHUDButtonCell *buttonCell; and then send it [buttonCell setButtonType:NSSwitchButton]; in awakeFromNib. This made the column "visible" again. Kind of a dirty trick, but at this point I'm mostly focused on getting my app ready...

timthedevguy commented 13 years ago

Thanks Tomaz, I'll check this out and see what I can find