Xcode 14 Beta 5 throws an exception - xcode

Xcode 14 Beta 5 shows this exception:
[<_UINavigationBarContentViewLayout valueForUndefinedKey:]: this class is not key value coding-compliant for the key inlineTitleView.
I am getting this new exception in all my obj-c projects while using Xcode 14 Beta 5.
A few notes:
Exception appears on any simulator device (running iOS 16)
Exception appears right on the start inside int main(int argc, char * argv[])
No exception on real device running iOS 15
Exception can be ignored (no crash).
I wonder if anyone else encountered this.

This is a bug in Xcode 14. Other users have reported it here: https://developer.apple.com/forums/thread/712240
Initially, the issue was reported in Xcode 14 betas, but the bug was never fixed, and now, here we are. I reproduce the issue in the official release of Xcode 14.0.1.
Here are workarounds that I've tested that will work:
Use a physical device: The issue doesn't occur when testing on a physical iOS device. I tested on an iPhone 13 Pro running iOS 16.0 with Xcode 14.0.1. The error doesn't occur then/there.
Ignore Objective-C exceptions: When the issue occurs, an Objective-C exception is thrown. Those are usually critical errors, but this particular exception is bogus. By default, Xcode always pauses the debugger when your app throws an Objective-C exception, but you can tell Xcode to stop doing that. In Xcode, go to the View --> Navigators --> Breakpoints menu. There, you'll see any/all breakpoints you have set. But one of the breakpoints appears there by default: "All Objective-C exceptions"; it has a dark blue arrow next to it, indicating that, yes, Xcode will indeed pause the debugger on all Objective-C exceptions.
If you click on that blue arrow, it will turn light blue, disabling the breakpoint. From then on, Xcode will ignore this exception, but, unfortunately, it will ignore all exceptions, even real exceptions that you actually care about. This may be enough to get you unstuck, but we'd normally want Xcode to pause on thrown exceptions (because they're normally very serious).
Add a condition to the "All Objective-C Exceptions" breakpoint: Since it's not great to just completely disable this breakpoint, we can do something cleverer. Enable the breakpoint (make sure its arrow is dark blue), then right-click on it and "Edit Breakpoint..." There, you can paste in this condition: !(BOOL)[(id)[$arg1 reason] containsString:#"_UINavigationBarContentViewLayout"] That will cause the breakpoint to pause execution on all breakpoints except breakpoints that contain the string _UINavigationBarContentViewLayout. Pretty good, I think! But every developer on your team will have to do this on every machine they use for testing. (Credit goes to Grigory Entin's comment)
Monkey-patch UINavigationBarContentViewLayout: Objective-C is a dynamic language, allowing you to add methods to a class at
runtime. This is called monkey
patching. It's normally
unwise to do that, and it's normally especially unwise to do it to
Apple's code. Apple normally won't allow you to submit apps to the
store that monkey patch Apple's classes. But, as long as you're just
doing it on your machine, and just to workaround a bug in the Xcode
simulator, there's no harm in it, right?
The code sample here is based on a post from the Apple Developer Forum by moshiwu.
#import <objc/runtime.h>
#interface Xcode14Fixer : NSObject
#end
#implementation Xcode14Fixer
+ (void)load
{
Class cls = NSClassFromString(#"_UINavigationBarContentViewLayout");
SEL selector = #selector(valueForUndefinedKey:);
Method impMethod = class_getInstanceMethod([self class], selector);
if (impMethod) {
class_addMethod(cls, selector, method_getImplementation(impMethod), method_getTypeEncoding(impMethod));
}
}
- (id)valueForUndefinedKey:(NSString *)key
{
return nil;
}
#end
Put that code at the top of your AppDelegate.m file, and then, at the top of your - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { method, add this line: [Xcode14Fixer load];
moshiwu attempted to use #if DEBUG to ensure that the code would only be used in debug mode, but that didn't work for me. Instead, just promise yourself that you'll remember to remove this debug code before you ship an official build to Apple, or Apple will probably reject your build.

Related

Backwards compatibility of new NSSearchToolbarItem

With macOS 11 Apple has introduced a new NSToolbarItem called NSSearchToolbarItem that automatically resizes to accommodate typing when the focus switches to the toolbar item.
Here Apple says this is backwards compatible with older versions of macOS: https://developer.apple.com/wwdc20/10104 (minute 11:50)
However launching my app with a NSSearchToolbarItem from interface builder on macOS 10.13 (High Sierra), crashes my app with the following Application Specific Information:
*** Terminating app due to uncaught exception 'NSInvalidUnarchiveOperationException', reason: '***
-[NSKeyedUnarchiver decodeObjectForKey:]: cannot decode object of class (NSSearchToolbarItem) for key (NS.objects); the class may be
defined in source code or a library that is not linked' terminating
with uncaught exception of type NSException
Launching it on 10.15 works fine. I haven't been able to test 10.14 yet.
Update 6 July 21 by Thomas Tempelmann
It turns out that this was a bug with older Xcode 12 versions and is now fixed in Xcode 12.5.1.
I had opened a bounty, because I had a seemingly related issue with the improper sizing of NSSegmentedControls inside the toolbar when running on High Sierra, but it turns out that this is a separate issue (which can be fixed by manually resetting the toolbar's minSize and maxSize to the control's frame.size).
Therefore, the solution is to use Xcode 12.5.1 or later.
Adding the item in storyboard without any code works properly, I have just tested. So probably you have done something wrong in the code. Or it is fixed in the latest XCode.
What I have found thus far is that this works only on Catalina, even on Mojave it crashes. According to #ThomasTempelmann it is better in XCode 12.5.1, but I haven't tested that yet.
There are two ways to solve this:
1. Use Xcode 12.5.1 or later
Build the app with Xcode 12.5.1 or later, wnhich appears to have fixed the compatibility with pre-10.14 systems.
2. Add the NSSearchToolbarItem in code
If you want to still be able to open the project with older Xcode versions (ie. Xcode 11 and earlier), you cannot place the new NSSearchToolbarItem into the storyboard, or older Xcode versions will refuse to open it.
In this case, you'd keep using the classic NSToolbarItem with an NSSearchField control inside it. The challenge is to replace it with an NSSearchToolbarItem when running macOS 11 or later.
I've tried several methods, such as explicitly removing the classic search toolbar item from the toolbar and then adding the new one, and implementing the delegate function to provide it. While that worked, it caused trouble when letting the user customize the toolbar: Then the dialog would keep showing the old search item along with the new one. The only way to resolve this was to access private functions (_setAllowedItems and _setDefaultItems), but I wasn't happy with that.
I finally found this fairly solution:
Create a new custom class, let's name it SmartSearchToolbarItem, and make it a subclass of NSToolbarItem.
In the storyboard, change the class of the Search Field from NSToolbarItem to SmartSearchToolbarItem.
Add the following code to the SmartSearchToolbarItem implementation:
#if __MAC_OS_X_VERSION_MAX_ALLOWED < 101600
#interface NSSearchToolbarItem : NSObject
- (instancetype)initWithItemIdentifier:(NSToolbarItemIdentifier)itemIdentifier;
#end
#endif
#implementation SmartSearchToolbarItem
-(instancetype)initWithItemIdentifier:(NSToolbarItemIdentifier)itemIdentifier
{
self = [super initWithItemIdentifier:itemIdentifier]; // this is necessary even if we won't use it, or we'll crash in Big Sur
Class cls = NSClassFromString(#"NSSearchToolbarItem");
if (cls) {
self = (id) [[cls alloc] initWithItemIdentifier:itemIdentifier];
}
return self;
}
Not only will this automagically replace the classic search item with the new one in Big Sur and later, it will even – and that's the part I don't really understand – still work with connected IBActions and IBOutlets. So, there's no need to copy and properties in code.
Fixing Segmented Controls
And if you happen to have segmented controls in your toolbar, then you'll also need this code to adjust their sizes as placement, as they have different widths on Big Sur vs. earlier macOS systems (10.15 and 10.14 will be fine, but if you also support 10.13, you will need this definitely):
- (void)fixSegmentedToolbarItemWidths // call this from `viewWillAppear`
{
if (#available(macOS 10.14, *)) {
// no need to set the sizes here
} else {
BOOL didChange = NO;
for (NSToolbarItem *item in self.view.window.toolbar.items) {
NSControl *control = (NSControl*)item.view;
if ([control isKindOfClass:NSSegmentedControl.class]) {
[control sizeToFit];
NSRect frame = control.frame;
const int padding = 2;
item.minSize = NSMakeSize(frame.size.width+padding, item.minSize.height);
item.maxSize = item.minSize;
didChange = YES;
}
}
if (didChange) {
[self.view.window.toolbar validateVisibleItems];
}
}
}
Sample code
Github page

iOS 8 today extension - recompile

I create an extension for my app in iOS 8 and it is displayed correctly under the Today tab.
However when I make a change to the extension (either a UI change in the Storyboard, a UI change in viewDidLoad code, or some changes in the widgetPerformUpdateWithCompletionHandler method), there's nothing that is changed when I recompile. The only way I can make the changes to appear is to delete the app from the device/simulator then compile/install again. Restarting XCode (I work with XCode 6 beta 4) / restarting the computer does not help.
How can I fix the bug?
How am I supposed to debug the extension, because setting breakpoints does not seem to do anything and no NSLog messages are printed to the console (I suppose, since it's a different target).
It's a known bug, read the release notes for iOS 8b5.
Debugging (and NSLog) works in Xcode but not always (known bugs). You can still attach the debugger if Xcode cannot attach himself (Debug -> Attach to process)
For me, the simulator works better than real device, so use the simulator until things got better.
2 tips:
Close the simulator at end of debugging (i have a script for auto closing the simulator when i press STOP in Xcode, tell me if you want it).
When you launch the plugin process in simulator, wait for "All applications" display list, if you click "Run" before the list are loaded, the debugger won't attach.

Main window doesn't run properly on Snow Leopard

My app developed in Xcode 4.5 on Mountain Lion runs flawlessly on Lion and ML.
My Snow Leopard tester reports that when the app starts, it is disabled. By that he means none of the controls are active and the red, yellow, green 'traffic light' is greyed out. If another app is opened that covers my app, when the covering app is moved, any control, or part of a control it covered is not there.
The menu bar is responsive, and my preferences panel works. The app can be shut down from the menu, I don't know if it can be shut from the keyboard.
Another app that uses the same serial code works fine.
I need help with putting together a plan to solve it. I don't know how to trace this.
Fundamentally, the problem is that you're expecting data to be in NSUserDefaults. On first launch, NSUserDefaults returns nil for the keys you access, and passing this nil result through later code causes exceptions to be thrown. The solution is to register defaults with NSUserDefaults upon application startup:
#implementation AppController
+ (void)initialize
{
NSDictionary *defaultValues = #{#"SomeKey" : #"DefaultValue"};
[[NSUserDefaults standardUserDefaults] registerDefaults:defaultValues];
}
#end

Out of the blue I can't get security scoped bookmarks

Blimey, this Sandboxing makes me despair: I have an app that's been released on Apple's store (so, in theory, it's gone through review...), it's a slide show player - nothing too fancy - the user can drag and drop images onto an NSTableView or select through NSOpenPanel. Anyway, I thought I'd use it myself so I recompiled a copy onto my laptop and all of a sudden I'm not allowed security bookmarking:
QuickSlide(1412) deny mach-lookup com.apple.scopedbookmarksagent.xpc
The above appears whenever I drag and drop images or select them through the NSOpenPanel.
I have the following entitlements:
The code I'm using to generate the bookmarks is:
-(NSData*)genSec:(NSURL*)aURL
{
NSError *error;
NSData *secData = [aURL bookmarkDataWithOptions:(NSURLBookmarkCreationWithSecurityScope | NSURLBookmarkCreationSecurityScopeAllowOnlyReadAccess | NSURLBookmarkCreationPreferFileIDResolution)
includingResourceValuesForKeys:nil relativeToURL:nil error:&error];
if (error) {
[self setReport: [NSString stringWithFormat:#"Can't access %# due to SandBoxing",aURL]];
return nil;
}
return secData;
}
Sure enough, the report method is also fired along with the Console logging.
It's never done this before in the months I did of development. I've also tried it on my dev Mac Pro crate, tried code-signing with different or no signing, and even downloaded it from the App Store (tried twice with 2 different accounts); all with the same result. I've also used the very handy Receigen app to check the entitlements in the compiled bundle. I'm running 10.7.5. The only thing that stops it from throwing errors is if I un-check the 'enable sandboxing' option in Xcode and compile.
Argghhh. Can someone point out the blindingly obvious mistake that somehow has slipped through 2 beta-testers, me, and an App Store reviewer...?!!!!
It has to be something obvious doesn't it?
UPDATE: I got a colleague to download a fresh copy to his laptop and there was no problem with sandboxing. I'd still appreciate it if anyone can shed some light on what's happening to my installs...
Todd.
Sure enough it seems from your entitlements that it is something obivous. You need to add this one as well:
com.apple.security.files.bookmarks.app-scope
I don't know why it was working before and now isn't, but I'm positive you need to declare this entitlement for security scoped bookmarks to work.

ios Zombie detection

I'm having (in my opinion) a very difficult problem in my code. It crashes randomly at different places in the code. The project is a ARC project.
So my program crashes occaisonally with this messages:
malloc: *** error for object 0xd2dd8b0: incorrect checksum for freed object - object was probably modified after being freed.
*** set a breakpoint in malloc_error_break to debug
I already set a breakpoint for malloc_error_break but I don't get any information out of it. When the code crashes ,XCode shows me the place in the code where it happens. But as I already said the crashes are randomly and do not occur always. But it seems as if the crashes are concentrated at on particular line in the code.
Now, I wanted to debug it using the instruments that come with xcode. After a bit of googling i found the following stuff on stackoverflow: How do I set up NSZombieEnabled in Xcode 4? and Xcode malloc error.
So the first link describes how to start zombie detection out of xcode itself by clicking the run button in xcode and choose "Profile". The problem I have is, that I cannot find "Zombies" when choosing the template for the trace document in my version of xcode (4.2). But if I start Instruments outside xcode (e.g. from finder) I can choose zombies.
Okay, here is what I did:
1) Start Instruments from finder and choose Profile "Zombies".
2) Start iphone app from xcode in the iphone simulator (normal run (not profile or debug)).
3) In Instruments "Choose Target"->"Attach to process"->"iPhone Simulator (57529)".
4) Instruments begins to recod something (I cannot figure out what it does).
5) Start playing around with the app until it crashes.
Eventually the app crashes and here is a screenshot of instruments after crashing the app:
My questions:
1) Is Zombies adequate for my problem or should I use another analyizes tool?
2) What tells me instruments in it's output after crashing?
Judging by your description of the problem, your crash is caused by something besides accessing a zombie object. If your app accesses a deallocated (zombie) object, Instruments shows a message like the following when using the Zombies template:

Resources