2

I've recently been handed a private hardware SDK to integrate into my company's mobile app. Everything works great except they are using a UIAlertView as the result of some opaque method call, and my design team wants to brand this. I don't have access to the SDK's source code. Is there a way I can safely swizzle UIAlertView to preserve all functionality and simply modify the appearance of the UIAlertView so it's more branded/consistent with the app appearance? If so, would I overload drawRect or something else, and how would I figure out what the names of the labels in UIAlertView are so that I can draw them with the size, shape, and color that I want?

for added detail, the app does not currently use UIAlertView or UIAlertViewController so in theory swizzling would only affect whatever is going on with this closed-source SDK.

helloB
  • 3,472
  • 10
  • 40
  • 87
  • Do you brand the other alertViews in your app, or do you use `UIAlertController`s and brand those? – Avi Feb 01 '16 at 18:08
  • @Avi We don't use UIAlertController other than via this API (and don't plan to as we do custom views). – helloB Feb 01 '16 at 18:29
  • i would recommend creating a custom controller rather then trying to swizzle. – Sumeet Feb 01 '16 at 19:15
  • @uchiha How can I create a custom controller when I don't have access to the source code? – helloB Feb 01 '16 at 19:16
  • I meant create a custom controller which behaves in the way similar to Alerts but it will be your class altogether, you do not need access to the source code. If you still want to use Alerts then go through http://code.tutsplus.com/tutorials/ios-sdk-uialertview-custom-graphics--mobile-8886 – Sumeet Feb 01 '16 at 19:23

1 Answers1

3

That wouldn't be straightforward at all.


If the SDK is using UIAlertView, then try swizzling the show method.

Your implementation should do approximately the following:

1) Do not let the original UIAlertView to show -- it is very hard to customize it.

2) Keep reference of old .delegate to be able to notify it when needed.

3) Create your own custom UIView and use [[UIApplication sharedApplication].keyWindow addSubview:myCustomAlertView];.

4) I believe you can get all of the previous UIAlertView variables (i.e. button titles, textFields, etc), using its properties such as

@property(nonatomic,copy) NSString *title;
@property(nullable,nonatomic,copy) NSString *message;
- (nullable NSString *)buttonTitleAtIndex:(NSInteger)buttonIndex;
@property(nonatomic,readonly) NSInteger numberOfButtons;
@property(nonatomic) NSInteger cancelButtonIndex;

5) Create your own designs and call corresponding delegate methods when needed.


Other approach is to use Apple's Private API, but this may lead to bad results.

This is a VERY HACKY approach. Firstly, you have no guarantees that it would even work. Secondly, your app may be rejected. Therefore, I wouldn't really recommend it...

However, if you really want to go with this approach, then try doing this:

After [myAlertView show]; look at its properties after some delay (i.e. 0.01 sec is enough):

enter image description here

Now look for suspicious properties (probably of UIView class), which might have UI-related information. For example, __representer looks quite interesting -- it has constraints, it has labelContainerView... Try playing with those properties.

In order to get that __representer, use KVC and KVO (i.e. start with id theAlertController = [myAlertView valueForKey:@"_alertController"];). Then dive deeper and deeper.

Hopefully, you would be able to find useful properties and would be able to change their values via KVC.

OlDor
  • 1,460
  • 12
  • 18
  • Thanks for this very thorough answer. I will try this out and let you know what happens. – helloB Feb 01 '16 at 19:30
  • You should also check, whether private SDK is using `UIAlertView` or `UIAlertViewController`. Hopefully, not both... In case they use both, you would have to apply method swizzling to both classes... – OlDor Feb 01 '16 at 19:33