Pixate / pixate-freestyle-ios

Pixate Freestyle for iOS

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

iOS 9 Crashes with styleClass All Over

cliftonlabrum opened this issue · comments

I just fired up my Pixate-enabled app in the iOS 9 simulator, and it crashes all over the place with messages like:

-[UITextField preventStyling]: unrecognized selector sent to instance 0x7fa8b96d6330

Failed to set (styleClass) user defined inspected property on (UITextField): -[UITextField preventStyling]: unrecognized selector sent to instance 0x7fa8b96d6330

and...

-[UISearchBarTextField preventStyling]: unrecognized selector sent to instance 0x7fda5af39350

Anyone know why this preventStyling thing is creating issues? I don't explicitly using it anywhere in my code. It appears to get called when using styleClass.

Oh man, I can't believe no one else has run into this. iOS 9 is about to hit, and if the Simulator is accurate, my app will be completely unusable because of Pixate.

Anyone successfully using styleClass runtime attributes on iOS 9?

Here's the full stack trace:

0   CoreFoundation                      0x000000010749cf65 __exceptionPreprocess + 165
1   libobjc.A.dylib                     0x0000000106f14deb objc_exception_throw + 48
2   CoreFoundation                      0x00000001074a558d -[NSObject(NSObject) doesNotRecognizeSelector:] + 205
3   CoreFoundation                      0x00000001073f2d97 ___forwarding___ + 487
4   CoreFoundation                      0x00000001073f2b28 _CF_forwarding_prep_0 + 120
5   PilotPro                            0x000000010438a3c0 -[PXVirtualStyleableControl preventStyling] + 85
6   PilotPro                            0x000000010436a0fc +[PXStyleUtils updateStyleForStyleable:] + 83
7   PilotPro                            0x00000001043812d8 -[UIView(PXStyling) updateStyles] + 317
8   CoreFoundation                      0x000000010738b85c __invoking___ + 140
9   CoreFoundation                      0x000000010749df49 -[NSInvocation invokeUsingIMP:] + 217
10  UIKit                               0x0000000105d0d773 __workaround10030904InvokeWithTarget_block_invoke + 84
11  UIKit                               0x00000001056b5fe1 +[UIView _performSystemAppearanceModifications:] + 66
12  UIKit                               0x0000000105d0d70d workaround10030904InvokeWithTarget + 1053
13  UIKit                               0x0000000105d07995 applyInvocationsToTarget + 1864
14  UIKit                               0x0000000105d06aac +[_UIAppearance _applyInvocationsTo:window:matchingSelector:onlySystemInvocations:] + 1888
15  UIKit                               0x00000001056d8a36 __88-[UIView(Internal) _performUpdatesForPossibleChangesOfIdiom:orScreen:traverseHierarchy:]_block_invoke + 64
16  UIKit                               0x00000001056d89c0 -[UIView(Internal) _performUpdatesForPossibleChangesOfIdiom:orScreen:traverseHierarchy:] + 189
17  UIKit                               0x00000001056d88d6 -[UIView(Internal) _didChangeFromIdiomOnScreen:traverseHierarchy:] + 182
18  UIKit                               0x00000001056d7ea3 -[UIView(Internal) _didMoveFromWindow:toWindow:] + 1743
19  UIKit                               0x0000000105792b41 -[UIControl _didMoveFromWindow:toWindow:] + 68
20  UIKit                               0x00000001056d7b32 -[UIView(Internal) _didMoveFromWindow:toWindow:] + 862
21  UIKit                               0x00000001056d7b32 -[UIView(Internal) _didMoveFromWindow:toWindow:] + 862
22  UIKit                               0x00000001056ec7d0 -[UIScrollView _didMoveFromWindow:toWindow:] + 85
23  UIKit                               0x00000001056d7b32 -[UIView(Internal) _didMoveFromWindow:toWindow:] + 862
24  UIKit                               0x00000001056d7b32 -[UIView(Internal) _didMoveFromWindow:toWindow:] + 862
25  UIKit                               0x00000001056ec7d0 -[UIScrollView _didMoveFromWindow:toWindow:] + 85
26  UIKit                               0x00000001056d7b32 -[UIView(Internal) _didMoveFromWindow:toWindow:] + 862
27  UIKit                               0x00000001056d7b32 -[UIView(Internal) _didMoveFromWindow:toWindow:] + 862
28  UIKit                               0x00000001056cd106 __45-[UIView(Hierarchy) _postMovedFromSuperview:]_block_invoke + 155
29  UIKit                               0x00000001056cd005 -[UIView(Hierarchy) _postMovedFromSuperview:] + 544
30  UIKit                               0x00000001056daac3 -[UIView(Internal) _addSubview:positioned:relativeTo:] + 1967
31  UIKit                               0x0000000105a83212 -[UINavigationTransitionView transition:fromView:toView:] + 672
32  UIKit                               0x00000001057fd27d -[UINavigationController _startTransition:fromViewController:toViewController:] + 3262
33  UIKit                               0x00000001057fd879 -[UINavigationController _startDeferredTransitionIfNeeded:] + 890
34  UIKit                               0x00000001057fe67d -[UINavigationController __viewWillLayoutSubviews] + 57
35  UIKit                               0x000000010599663d -[UILayoutContainerView layoutSubviews] + 248
36  PilotPro                            0x00000001043a6825 callSuper0 + 55
37  PilotPro                            0x000000010438b259 -[PXUIView layoutSubviews] + 47
38  UIKit                               0x00000001056de11c -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 710
39  QuartzCore                          0x00000001053ab36a -[CALayer layoutSublayers] + 146
40  QuartzCore                          0x000000010539fbd0 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 366
41  QuartzCore                          0x000000010539fa4e _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 24
42  QuartzCore                          0x00000001053941d5 _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 277
43  QuartzCore                          0x00000001053c19f0 _ZN2CA11Transaction6commitEv + 508
44  QuartzCore                          0x00000001053c2154 _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 92
45  CoreFoundation                      0x00000001073c89d7 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
46  CoreFoundation                      0x00000001073c8947 __CFRunLoopDoObservers + 391
47  CoreFoundation                      0x00000001073bdebc CFRunLoopRunSpecific + 524
48  UIKit                               0x000000010562898d -[UIApplication _run] + 402
49  UIKit                               0x000000010562d676 UIApplicationMain + 171
50  PilotPro                            0x000000010417cf84 main + 132
51  libdyld.dylib                       0x000000010798892d start + 1

The problem appears to be specific to UITextField. I tried removing any styles that reference them but the same thing happens. The mere presence of a UITextField in a view causes the crash.

I'll take a look today.

-Paul

On Sep 14, 2015, at 9:20 PM, Clifton Labrum notifications@github.com wrote:

The problem appears to be specific to UITextField. I tried removing any styles that reference them but the same thing happens. The mere presence of a UITextField in a view causes the crash.


Reply to this email directly or view it on GitHub.

Any luck, @pcolton?

+1

It only seems like it is a simulator problem?

+1, and I also notice that this is only a problem in the simulator.

Yep, Simulator only. Pretty crippling for any development work, though.

+1 same here un-styled UITextField

+1 Same here. It was working fine until I upgraded to El Capitan. Was working on Xcode 7

This is quite strange. Here is the line that is causing the issue:

    BOOL preventStyling =
        ([styleable respondsToSelector:@selector(preventStyling)] && [styleable preventStyling]) ||
        ([styleable respondsToSelector:@selector(viewStylers)] == NO);

And the error message:

-[UITextField preventStyling]: unrecognized selector sent to instance 0x7fe905185b40

UITextField should not recognize the selector preventStyling, so this one should not be called, since the && operator should not execute the right-hand part of the expression.
BUT: setting a breakpoint it turns out that [styleable respondsToSelector:@selector(preventStyling)] is true... Why? No clue.

As a workaround, I tried to implement the "ghost" methods in a category:

#import "UITextField+PixateElCapitanSimulatorBug.h"

@implementation UITextField (PixateElCapitanSimulatorBug)

-(BOOL)preventStyling {
    return NO;
}
-(BOOL)playsNicelyWithGestures {
    return YES;
}
-(BOOL)_isInteractiveTextSelectionDisabled {
    return YES;
}
@end

and now my app is not crashing anymore..
What's happening though? Has respondsToSelector: become unreliable in El Capitan + Xcode 7 + iOS 9 simulator environment?

This works but only up the point where you need to input text, then Im getting respondsToSelector crashes for _shouldRepeatInsertText:(BOOL)arg1 and _delayUntilRepeatInsertText:(id)arg1. Adding these to the category stops the crash but input fails on the Sim and device. I assume as these are private methods we can't update the internal properties? And even if we did would this pass approval?

Not sure it's OS9 per se, was working fine here until I upgraded Xcode to 7.0.1/elcapitan, my other mac hasn't got 7.0.1 on it yet so Im adding 7.0 now. Otherwise OSX rollback may be required.

So.. after some more investigation the issue seems to be somewhere in the custom Freestyle's respondsToSelector: implementation:

static BOOL respondsToSelectorIMP(id self, SEL _cmd, SEL selector)
{
    return ((BOOL)callSuper1v(self, [self pxClass], _cmd, selector))
            || (class_getInstanceMethod(object_getClass(self), selector) != NULL);
}

Removing this part: (BOOL)callSuper1v(self, [self pxClass], _cmd, selector)) everything works as expected. No idea why but maybe this helps @pcolton ?? This is the callSuper1v implementation:

void* callSuper1v(id self, Class superClass, SEL _cmd, void *arg1)
{
    struct objc_super super;
    super.receiver = (__bridge void *)self;
    super.class = superClass != NULL ? superClass : class_getSuperclass(object_getClass(self));

    void* (*objc_msgSendSuperTyped)(id self, SEL _cmd, void *arg1) = (void*)objc_msgSendSuper;

    return objc_msgSendSuperTyped((id) &super, _cmd, arg1);
}

As far as I understand it the method check if the super class of self responds to the selector selector, but honestly I have no idea on how to further debug this. In this case, self is an instance of PXUITextField_UITextField.

+1 on this issue.

Running El Capitan w/Xcode 7 and am seeing this error when attempting to run the Simulator.

Has anyone else made any progress on a reliable workaround to get on with development?

Currently Ive copied NSObject+PXClass.h, NSObject+PXSubclass h/m, objc.c & objc.h to my project, then edited NSObject+PXSubclass to remove the callSuper1v ref from respondsToSelectorIMP() and also supressed the assert for 'doesn't fit for subclassing' @ L63. This means I can compile fine & textfields can be edited. Only issue Ive seen is in the Sim trying to tab between fields fails, this is not an issue. Maybe time for a rethink on it's use seeing as it's pretty dead here, but quite a bit of work!

@neilkachu Thank you for the quick response. I will give that a shot now.

np, here's hoping pcolton has time to fix it properly soon.

@neilkachu I am new to iOS dev, and can't seem to locate some of the files you mentioned before. I am having trouble locating the .m files for most of the files you named. Is there some special step I need to take to locate these?

If you've used the pod you'll also need to get the source from here too as the pod will only contain the .h files.

Ahh...thank you! That would be the issue!

I still have not solved this issue. Anyone know of any alternative solutions?

I don't have much confidence in the long-term maintenance of Pixate (as demonstrated with this issue), so I have since moved away from Pixate. I'm styling things in the Storyboard editor and using the UIAppearance API now.

@mmckinley8 I have been looking at this for a while now, and as an iOS noob, I was unable to completely work out what I needed to do in the workaround suggested by @neilkachu . At the moment, I am working on understanding swizzling in objective-c so I can try and override the offending lines. Not 100% sure if that will work either, but at the very least, I am getting more familiar with objective-c - even if I can't run my project to do any actual work! 👍

For the record, switching to iOS 8.4 simulator made the problem go away, so unless you are working on iOS9-specific stuff, that should at least let you get some work done. Hope that helps.

Hmmm... I plan to use PixateFreestyle in Xcode 7.0.1, iOS 9 and Swift 2.0 in next release. If there is a problem I need to know NOW. But, I tried it out by creating a simple app with three object, label, button and text field. I sat styleClass and styleID both programmatically and in story board and I did not see any error. Object-C only maybe? Thanks.

It's certainly possible that this is an Objective-C only issue. If you are running your Swift app in the Simulator and it's not crashing after adding a UITextField to your app, then you are good to go.

Just be mindful that Pixate may not be a reliable codebase to use going forward since it has mostly been abandoned.

I actually just read that Pixate was acquired by Google while searching deeper about Pixate and their planned support level. Not sure if that bodes well or not for this package, but it did happen according to the Pixate Website.

Right, but Google is most likely interested in Pixate's prototyping tool. Freestyle (the name of the CSS library) has been set aside: https://github.com/Pixate/pixate-freestyle-ios/graphs/contributors

Suggested solution kills another UITextField functionality
For example not possible to set keyboard type if remove ((BOOL)callSuper1v(self, [self pxClass], _cmd, selector))

Given the Pixate team is extremely busy these days, we're looking both
internally and externally for contributors to help continue and take the
project further.

On Fri, Oct 16, 2015 at 9:18 AM, Clifton Labrum notifications@github.com
wrote:

Right, but Google is most likely interested in Pixate's prototyping tool.
Freestyle (the name of the CSS library) has been set aside:
https://github.com/Pixate/pixate-freestyle-ios/graphs/contributors


Reply to this email directly or view it on GitHub
#186 (comment)
.

FYI: this only occurs for iOS9 64bit device simulators, an iP5 is fine and 5S is not. Ive added this hack only to specific targets so it doesn't affect release/adhoc builds. Given this project is effectively un supported now, this will do. All new projects are Swift and this isn't occurring with these but an alternative method for this will likely be required, pity. So only 64bit >8.4.1 simulators are affected.

None of the above solutions have worked for me. I can only get the project to build on my phone when it is on production. Does anyone else have an alternative solution that has worked for them?

Hi mmckinley8,

I used styleClass and styleId with object-C and Swift both in my project
and I didn't experience any crashing issue because of those. I would
suggest you look at your CSS file content and make sure it is valid. I
found out, invalid CSS is deadly to Pixate. There is a flag you can set in
Pixate config file to check validation. You can Google it.

P.S. We gave up using Pixate's Freestyle to theme our application because
there is no activity in their support team to support iOS 8 introduced iOS
control namely, document picker and UIAlertController just to name a few.
Without Pixate provided style selector, it is very hard to theme the
control correctly. But source code is available if you want contribute to
the Freestyle. Good luck.

On Sun, Nov 29, 2015 at 9:03 PM, Ronaldo Gomes notifications@github.com
wrote:

+1


Reply to this email directly or view it on GitHub
#186 (comment)
.

Hi @Dune2015,

I am sure the css file is fine, this is what is in it.

.loginSignupNavigationArea {
    background-color: #EF4437;
}

.loginSignupLogoArea {
    background-color: gray;
}

.formLabel {
    font-size: 10pt;
}

.formField {
    border-width: 2pt;
}

It is very simple, still evaluating the framework to whether we should use it or not.

Since you gave up using it, what are you using instead?

CSS file looks OK to me. I am using old fasion way of theming iOS app by
using Appearance Proxy and API. Thanks.

P.S. you might want to check where Pixate found that default.css file.
There is a path property that you can print to examine if that is the place
where your default.css file resided.

On Mon, Nov 30, 2015 at 3:05 PM, Ronaldo Gomes notifications@github.com
wrote:

Hi @Dune2015 https://github.com/Dune2015,

I am sure the css file is fine, this is what is in it.

.loginSignupNavigationArea {
background-color: #EF4437;
}

.loginSignupLogoArea {
background-color: gray;
}

.formLabel {
font-size: 10pt;
}

.formField {
border-width: 2pt;
}

It is very simple, still evaluating the framework to whether we should use
it or not.

Since you gave up using it, what are you using instead?


Reply to this email directly or view it on GitHub
#186 (comment)
.

I am not sure why it is needed to replace the implementation for respondsToSelector:, but what I did is to comment out the code responsible for method swizzling:
`// respondsToSelector:

Method respondsToSelectorMethod = class_getInstanceMethod(superClass, @selector(respondsToSelector:));
class_addMethod(newClass, method_getName(respondsToSelectorMethod), (IMP)respondsToSelectorIMP, method_getTypeEncoding(respondsToSelectorMethod));`

After this change all works fine for me on the phone and in the simulator.

Removing this swizzle will break UIKit in many places. It is not reproducible easily, but that didn't work well. Correct solution is to use different technique for swizzling (I have implemented this in StylingKit)

I just hit this issue. Going to try installing older simulator version to keep working. Any news?

Id forget it, I doubt this is ever going to be fixed but there are a few new alternatives for instance:

https://github.com/tombenner/nui
https://github.com/146BC/StyleKit

good luck.

I have found that Pixate (and libraries like it) are mostly unnecessary now. The UIAppearance API is easy to use and Xcode 8 includes some new features that make handling global colors even easier. I do all my styling either via the Storyboard Editor or UIAppearance. Good luck!

React Native is also another option nowadays. It has CSS styles support with flexbox. You can gradually replace your existing native views with it, here is a blog post about it: https://hashrocket.com/blog/posts/tips-and-tricks-from-integrating-react-native-with-existing-native-apps