While searching a bug in my code today I found a strange thing. When inspecting a UIView instance in the debugger the variable view of Xcode does not show the subviews member of the UIView class.
I only see this fields in the debugger (> should indicate the opening triangle):
UIResponder
_layer
_tabInfo
_gestureInfo
_touchData
_charge
_tag
_viewFlags
I'm missing the _subviews member and come to think of it also all the positional members (at least one of them should be there).
Does anybody know what I'm missing or doing wrong (as far as I can tell it is not a problem as a google search for this problem didn't got me any results).
I use Xcode version 3.1.3 with:
XcodeIDE: 1191.0
XcodeCore: 1192.0
XcodeSupport: 1186.0
on a mac with OS 10.5.7 and iPhone SDK 2.2.1 (I also tested with iPhone SDK 3.0).
I hope somebody knows anything about this. It gives me a little strange feeling that I cannot trust the debugger to show me everything I should know for debugging a problem. And it's not good if you need to mistrust you tools :(
The debugger is only going to be able to show you members, not properties. Remember that the two are different in Objective C. A property is just syntactic sugar for a setter and/or a getter. So the read-only "subviews" property of UIView only guarantees that it has an implementation for this method:
- (NSArray *)subviews;
As you've noticed, Apple has implemented many of their properties using undocumented member variables that resemble their corresponding property names, but with leading underscores. This allows you to spy on the internals of some objects to see what's going on in some cases, but many properties aren't implemented in such a transparent manner. In these cases, you'll need to inject some diagnostic code into your app to access the property and output its return value using NSLog, and/or store the value in a temporary variable that you can observe in your debugger.
Don't blame the poor debugger. It's doing exactly what it's designed to do. If it helps, you can blame properties for trying to trick us into thinking they're member variables when they're really methods.
Related
I have seen a few articles or video's on iOS 15's new Self._printChanges() function, but can not find any documentation on it anywhere. Does anyone know where Apple documented this new function? It is pretty obvious how to use it, but I would like to see what more we can do with it and knowing more about it would be helpful. Even Xcode's lookup's yield nothing. Anyone find anything?
Unfortunately, _printChanges() is a private API, which is why it's undocumented. The only reason so many videos and articles referenced it is because an Apple engineer mentioned it during WWDC21. Here's what they said:
It's not technically API-notice the leading underscore — so should only be used in debugging. My one sentence pro-tip is the extent of the docs I'm afraid.
However, Xcode does show a summary when you Option + Click.
Summary
When called within an invocation of body of a view of this type, prints the names of the changed dynamic properties that caused the result of body to need to be refreshed. As well as the physical property names, “#self” is used to mark that the view value itself has changed, and “#identity” to mark that the identity of the view has changed (i.e. that the persistent data associated with the view has been recycled for a new instance of the same type).
SwifterSwift has a property name cornerRadius.
It's an extension to UIView.
While the DropDown framework has a property name cornerRadius.
DropDown (the class) is a subclass of UIView.
It seems like xCode doesn't know which property I'm referring to.
I only imported one framework to my file but SwifterSwift's extension still takes effect.
I modified the DropDown framework and everything worked fine but then I reverted because it's not allowed and I wouldn't know how to debug any future problems.
I also tried creating a function in an extension to somehow get around this problem.
It turns out that I can't directly access DropDown's table (which is the view that we round).
I cant remove the SwifterSwift framework because it has already been used in the project that I'm working on. Although that might be the best option.
Is there a solution to this problem ?
In Swift, namespaces are implicit and belong to target it is defined. So, for your case, the workaround would be to add the target name in the property call.
SwifterSwift.cornerRadius
DropDown.cornerRadius
Let take example of String. It belongs to Swift target and so I can do this
let str = Swift.String("abc".characters)
Please follow the steps in this issue
Or upvote for adding prefix to all SwifterSwift extensions here
I want to understand how to implement a key logger for iOS. And how can I avoid logging keys in my application, if there is iKeyMonitor (for example) installed on device?
After research I found that ikeyMonitor installs the following files on the device:
Library/Caches/.keycache
Library/MobileSubstrate/DynamicLibraries/MobileSafe.dylib
Library/MobileSubstrate/DynamicLibraries/MobileSafe.plist
Library/MobileSubstrate/DynamicLibraries/keychain.dylib
Library/MobileSubstrate/DynamicLibraries/keychain.plist
Of course it requires MobileSubstrate.
In keycache there are some HTML files that I can open in Safari with the URL localhost:8888.
In the plists there is only com.apple.springboard filter, it means that MobileSafe.dylib (and all hooks) will be applied only on
springboard app.
Even if I don't use the default keyboard view in my app for editing a UITextField, the keylogger still works. This means that Hooks are applied on UITextField.
After using class-dump for SpringBoard.app I didn't find any methods that can be related in UITextField's implementation. After using class-dump for MobileSafe.dylib I didn't find any implementation that can be substituted for UITextField either (maybe because it written on C), I think that I should analyze MobileSafe.dylib dynamically with gdb
How can the SpringBoard (that is in plist com.apple.springboard) app have an effect on UITextField class implementation? If I use method swizzling for UITextField in the dylib for com.apple.springboard will it work in other applications too?
What is the general difference between MobileLoader and MobileHooker? At what moment will changes from MobileHooker will be applied to my system?
What should I do to hook a method from UIKit (for example UITextField methods), and change its implementation for all apps on my device?
What method for analyzing iKeyMonitor can you advise me to use?
if it uses springboard in the filter then it can only affect the springboard, to hook all applications you use UIKit as the filter(more on that in 3)
My understanding of the two is that:
MobileLoader loads your code into the running application and when this happens, functions with the constructor attribute "__attribute__((constructor))" are called. In one of these constructors, MobileHooker functions are called to replace pre-existing functions/methods in the application. As for when the changes are applied, since they are changed in constructors they should be changed before any of them are actually called.
You simply use the com.apple.UIKit filter(which btw is what the keychain.dylib in iKeyMonitor uses)
class-dump does not show the hooked classes and methods of a tweak because they are not objective-c methods, instead they are functions...
The best option would be a disassembler like ida hex-rays.com/products/ida/index.shtml
Is there any way that one could extract the information about UI elements (of the UIView) from the application’s memory during runtime of an iOS application (iPhone). Like getting a reference to the current UIView element and find a way to enumerate all UI elements contained in that view and create an abstract graph of the UIView calls of the app dynamically?
Since it looks like you may be interested n some general suggestions, I'll give you this one: look at DCIntrospect (available on github, with good documentation).
With this open source software, you can examine any item in your UI that subclasses UIView. You can see its many properties in your console.
It is very easy to use. I tried it, and it was a very simple add to my application delegate. To enable it, you press the space bar on your keyboard.
Since it is open source, you can examine the code and see for yourself what UI element properties are available and even make changes yourself.
UIView comes with an undocumented function to do that: -recursiveDescription. It's not as pretty as DCIntrospect, but you don't have to add anything to your project. Simply do:
NSLog(#"%#", [view recursiveDescription]);
or you can call it from the debugger:
p [view recursiveDescription]
See Apple's Technical Note 2239 (scroll to the bottom) for more details, and other interesting debugging commands.
I've tried removing cache, clean all targets, etc.
Instance variables from my super class are getting highlighted green according to my color scheme, but the compiler then fails saying
"score" (or whatever) undeclared"
If I have two references in one method, only the first one fails. If I leave them out, or use instance variables from my subclasses header, the app compiles and runs fine.
It was working literally just 2 days ago. I wonder if I accidentally hit a shortcut that turned on some weird setting?
It's running in the 3.2 iPad simulator, if that matters.
It's a weird one.. hope someone has run into this before.
Sounds like your instance variables are declared as #private. This means that only that exact class can access them. If you want subclasses to access the ivars directly put #protected above them, eg
#protected
id myiVar;
NSString *myStringIVar;