Import UIKit for debugging Objective-C by default - objective-c

Whenever I try to read the frame of an UIView for example while debugging, I get this error:
error: property 'frame not found on object of type 'UIView *'
error: 1 errors parsing expression
After searching for a solution, I found out that I can use this command to solve this without adding (annoying and in some cases complicated) casts:
expr #import UIKit;
But I still find it annoying to have to do this every time (why doesn't Xcode do this by default?!), so I thought I should be able to do this using the .lldbinit file, but I couldn't get it to work.
I don't know much about that file, I have this in it atm:
command script import /usr/local/opt/chisel/libexec/fblldb.py
so I tried adding the UIKit import command at the end of the file but it didn't look that it worked. I also tried prefixing it with command to no avail. Is this possible or not? (please say yes; it will save my life)

lldb will auto-import modules that the debug info tells us the program imports fairly soon now. All the pieces weren't in place to do that for the first Xcode 7 releases.
Statements in the .lldbinit get run before the main file is read in, it is supposed to help set up the environment to read in your program. But at that point there's nothing into which to import these symbols. You need to do it after the main binary is read in (and you really need to do it after you have run, since I think we need to run some code to do this.)
At present, the simplest way to do this is to make an auto-continue breakpoint at main, and attach the expr #import UIKit statement as a debugger command in that breakpoint. You'll have to do this once per new project you make, but if you're working on the same project for a while, it's not such an inconvenient workaround.

Related

Xcode cannot find ProductModuleName-Swift.h

I'm attempting to import my "-Swift.h" file into one of my Objective-C .h files but xcode keeps telling me that the file doesn't exist
#import "Aesculus-Swift.h"
If I command click on the file name it will take me to the generated header file so I know it exists. Why is xcode not able to find it?
This seems like just another issue with Xcode and it's complex tool chain of static analysers and compilers.
Openradar lists radar://21362856 - Swift to Objective-C bridging is unreliable. I am sure there are more but I stopped looking after finding one for this example.
The author imarcelv notes in the description:
I asked a Swift engineer at WWDC in a lab and even he didn't know how to fix this issue.
Steps to Reproduce:
Add a ramdom Swift class to an Objective-C project
Add the #import "ModuleName-Swift.h" file that Xcode generates automatically
Try to use it or just try to compile the project
From time to time it simply doesn't work
It's probably best to file a radar on this issue as it seems that others are already calling it out.
One other thing you could try...
Historically, it was possible for Xcode to completely lose it's syntax highlighting and you could always find out what files the static analyser was giving up on by increasing log level of clang.
I'm not sure if it's still relevant but if I was in your position I'd be trying this command:
defaults write com.apple.dt.Xcode IDEIndexingClangInvocationLogLevel 3
This generates logs you can search with using Console.app for just xcode to highlight the messages. You'll want to trash the derived data of your project to force it to re-compile things.
Although not the same issue as what you're seeing, I have had this post on the syntax highlighting issue bookmarked for years for the above defaults write command to try in times like these.
I solved this recently by adding the following entry to my .xcconfig (you could add it in Xcode's Build Settings > User Header Search Paths if you prefer).
USER_HEADER_SEARCH_PATHS = $(BUILT_PRODUCTS_DIR)/MyFramework.framework/Headers
This tells the compiler to search for headers in the build output directory, which is where Xcode puts the generated header (at least in the case of this framework).
In my case this is a directory like ~/Library/Developer/Xcode/DerivedData/MyProject-LongCode/Build/Products/Debug-iphonesimulator/MyFramework.framework/Headers/MyFramework. You might find your generated header in there too.
Xcode's header and dependency management is a hot mess, and it's not surprising that it doesn't work for you.
I had trouble with this stuff & found that your -Swift file is the Product name of your Target ( not just the name of your Target ) . I found the details here helpful: http://ericasadun.com/2014/08/21/swift-calling-swift-functions-from-objective-c/
When you encounter such situation, just find your kinda "ProductName-Swift.h" file by just cmnd+click on it (even if xcode shows warning about it is not found, the #import "Aesculus-Swift.h" string is still clickable) and then in opened code editor window choose context menu and "Show in Finder" item, then explicitly add it to your project.

How to avoid "Redefinition" and "Duplicate Protocol" definition errors in Bridging Header

I want to use a objc library and a objc class in a swift class. So I place the following in the Bridging-Header.h:
#import <FooLibrary/FooLibrary.h>
#import "FooClass.h"
The problem is that the FooClass.h has
#import "FooLibrary.h".
So when I compile I get hundreds of errors like:"Redefinition of enumerator" and "Property has previous definition" and "Duplicate protocol definition" and "Typedef redefinition"
How do I avoid this? It seems like this is just a stupid mental block I am having but I can't get past it so here I am asking.
PartiallyFinite suggested I watch for #include
I did a project wide search and I and not using it at all. There are a few in the library. I chose one of the errors. The file the decoration is in is never included in any file with #include
Sounds like something is causing the preprocessor to believe that the FooLibrary.h header imported indirectly by the second #import is somehow not the same file as the one you include just above it. My best guess as to what is that your first, framework-style import is referencing header files that are copied to a build location during build, while your second, direct file import is referencing the header file as it is in your project directory, meaning that the preprocessor sees them as two completely separate files, resulting in it being imported twice.
Proposed ways to fix:
If you can include FooClass.h using the framework-style import syntax (like #import <FooLibrary/FooClass.h>), that will probably fix the problem.
If you're absolutely sure that FooClass.h will always include FooLibrary.h, you can probably just omit the first import entirely, as everything will get imported indirectly via the second one.
Otherwise, you can try some nice, old-fashioned include guards (assuming you have write access to the library headers):
// FooLibrary.h
#pragma once // Maybe even throw in one of these for good measure;
// since we're dealing with an obscure-sounding bug,
// may as well try to fix it in all of the possible ways
#ifndef FOOLIBRARY_IMPORTED
#define FOOLIBRARY_IMPORTED
... // actual file contents
#endif
This will define a preprocessor macro the first time the file is imported, so the second time the preprocessor tries to import the file, the already defined macro will prevent the contents from being imported a second time. I fail to understand why the #import isn't doing this in your case, as that's literally its only purpose and advantage over #include, but if this fixes it, ¯\_(ツ)_/¯
This can also be caused by cocoapods - try upgrading or downgrading to a different version and re-running pod install
For me it was happening when I upgraded Xcode. All I did was to Clean Build folder and run again and it worked!

xCode: Accessing properties of an object via console

Is it possible to access the properties of objects in xCode console?
If I try the following I get an error that he property doesn't exist.
po someObject.someprop
If I don't breakpoint the code and run the app it works fine so I know someObject.someprop exists. I don't think I have the grasp on xCode console yet? What I loved about Flex/Flash development is that I could set a break point and in the console window or variables view I could traverse every structure down to the ends of the earth.
I could see SomeDicionary[key].someArray[1].someObject.prop and it would show me the value. Is this not possible in xCode console or is there a trick to get to it?
You'll actually have to use the bracket syntax notation:
po [someObject someprop]
The debugger is sometimes very finnicky about syntax. This is filled with all sorts of helpful tips for debugging in XCode.
Just a side note, variables/properties declared in the implementation file (*.m) instead of the header file (*.h) can sometimes be invisible to the debugger variable list display depending on if the breakpoint is in that class's code, because of scope. Not necessarily required here, but useful to know seeing as how it is kind of relevant.

Xcode4: with categories: ... Class method ... not found (return type defaults to 'id')

I keep getting this for situations that are patently false, related to objective-c categories.
NB: this was working fine, then stopped working overnight.
It's as if Xcode is fundamentally broken in it's ability to "read the file system", and it's driving me nuts. Any ideas on how to force it to ... read the file system ... would be appreciated.
e.g.:
Start Xcode, write a file, import it, using Xcode autocomplete.
cmd-click on the import line, and it jumps to the header file
A few builds later, Xcode flags a Warning:, e.g. "Class method '+stringFromCGPath:' not found (return type defaults to 'id')"
Now when you cmd-click on the import line, Xcode flashes up a dialog "Symbol not found" (world's worst dialog box? doesn't even have a confirm, it flashes and vanishes)
If you run the app, it crashes on that line, saying the selector not recognized
Then, to prove how FUBAR Xcode is:
Quit Xcode, restart
Cmd-click is working again
...but the Warning is still in place, and the app still crashes
After a few seconds, cmd-click stops working
NB: things I've checked:
The file is in the project folder? YES
The .m file is included in the Target? YES
The .m file is in the list of files to compile? YES
Do a CLEAN ... then a BUILD? YES
UPDATE: an example header I'm trying to import - that I have been successfully importing for months, and worked fine in hundreds of builds, and I have NOT changed (confirmed using SCM):
#import <Foundation/Foundation.h>
#import "CGGeometryExtensions.h"
#interface NSString(CGPath)
+(NSString*) NSStringFromCGPath:(CGPathRef) path;
#end
UPDATE2: actually, this doesn't crash at runtime - it was crashing because there was a typo in the call to "NSStringFromCGPath:" (one letter was lower case when it should have been upper case). But this was hard to see because of XCode's claim that the whole header file didn't exist - even though, as noted above, the IMPORT line was auto-generated by Xcode.
It sounds as though you may have problems with the indexer. Have you got multiple targets in your project, or multiple projects in a workspace? If so, make sure they all build completely cleanly - a failure indexing one target can mess up code completion on another.
You might also try deleting your project's DerivedData folder

Removing a method call from inside a static lib(.a) without recompiling

I'm using a static lib thats giving me a warning when uploading my binary for review by apple.
The method in the static lib that causes the warning(non-public selectors) is never called by me, its corresponding .h is deleted from my proj, but warning still persists.
Given that I know the method name causing the problem, is there a way for me to open/edit this .a and comment/delete the offending piece of code and then use the modified .a in my project.
I don't have access to the .a source to recompile it, and its very old and the creator of it has no contact details for me to track down.
Many Thanks,
-Cake
Quick and dirty solution: Open the .a file in a hex editor and change all instances of the name. Leave the function name the same length so that offsets in the file don't change, just change a letter or something like that. I did a quick test, adding a dummy function to a subproject we're building as a static library then tweaking the function name in the .a file (there were five instances, for what that's worth) and everything built okay. I don't see any reason it wouldn't pass the App Store check after that.
I'm really surprised the function was still there in the final build, though—I thought Dead Code Stripping was supposed to clean out any unused code. Huh.
http://opensource.apple.com/source/cctools/cctools-809/
I don't presume to get your bounty, because I haven't provided an easy solution. But yes, it in theory is possible. You have your work cut out for you.
There are several solutions, depending on your lib and project.
In your build settings :
Enable "dead code stripping" if possible : If the method is never used (even internally), the symbol will be deleted.
Use "Unexported symbol file" : Simply add the symbol into a file and it will be removed from the binary. This will work even if the symbol is used internally.
Enable "Deployment Postprocessing" and "Strip Linked Product" with "Strip Style" set to "All symbol"
(Not sure) Use "Symbols Hidden by Default". This is related to the code generation and should not affect linking, but just in case everything above failed...
No need to hack the binary files. Just turn off the compiler's "unused selectors" warning: -fno-unused-selectors.