Initialising swift view controller with nib name in objc class - ios

In my app I have a view controller written in Swift. I imported it in to app delegate which is written in objective c. I try to create an object of the swift view controller like this
ListAllSongsViewController *songListVC = [[ListAllSongsViewController alloc]initWithNibName:#"ListAllSongsViewController" bundle:nil];
The ListAllSongsViewController is written in swift. The project compile without any issue but when executing the above line the app crashes & stops at init method of ListAllSongsViewController
There is nothing in the log, it just stops. Zombie & All exception break points are enabled.
P.S. It only crashes in device (iOS 7.1), but works fine in simulator
Update :
Getting the same issue even if I use the default swift initialiser
ListAllSongsViewController(nibName: "ListAllSongsViewController", bundle: nil)

Usually occurs when you passed a wrong nibName. Considering it crashes only in device, I think you've made a mistake about the case of the string ListAllSongs, because the Mac/Simulator's file system is case insensitive while the device is not.

Related

Does AudioKit 4+ support AKFrequencyTracker with Objective C?

I'm trying to incorporate AudioKit 4.0.3 (latest) into an existing iOS ViewController that's written in Objective C. I am having trouble initializing and using the AKFrequencyTracker class, even though other classes work fine (e.g. AKOscillator and AKMicrophone).
I added the following code to the ViewController viewDidLoad method in the Objective C example that came with it:
AKMicrophone *mic;
mic = [[AKMicrophone alloc] init];
AKFrequencyTracker *tracker;
tracker = [[AKFrequencyTracker alloc] init:mic hopSize:512.0 peakCount:20.0];
But I see an "No visible #interface for 'AKFrequencyTracker'" error in Xcode next to the last line.
It doesn't appear there are any init methods for AKFrequencyTracker. Any help would be greatly appreciated!
Due to a change with Swift 4 we need to explicitly add #objc to the init methods and forgot to do so with AKFrequencyTracker. I just fixed it in this commit:
https://github.com/AudioKit/AudioKit/commit/e9328d4aa8d76d0cae31eeb33b232abebd571d6e

Swift 4 Error Running Code in Extension

I'm trying to upgrade my iMessage App to Swift 4. This section of example code worked perfectly in Swift 3 but gives errors when trying to move to Swift 4. The code below is in a class where the file is part of the main app target as well as the iMessage app.
#if IN_EXTENSION
// Do nothing since it's running in iMessage Extension
print("In extension")
#else
let helper = Helper()
helper.test()
UIApplication.shared.shortcutItems = []
let mainStoryboard = UIStoryboard(name: "Main", bundle: Bundle.main)
let testViewController : UIViewController = mainStoryboard.instantiateViewController(withIdentifier: "Test") as UIViewController
UIApplication.shared.keyWindow?.rootViewController = testViewController
#endif
It gives errors such as shared is unavailable. Which makes total sense since it's not available in iMessage Apps.
How this worked previously is in Other Swift Flags I added -DIN_EXTENSION to the iMessage app extension but not the main app.
There are a lot of similarities between my iMessage App and main app. So I want to keep my code clean and not repeat code. So this should be possible.
I'm not sure why after converting to Swift 4 all the sudden it's throwing errors.
Any ideas on how to fix?
For some reason after rebuilding my app just now this error went away and it gave me completely different errors. After solving those this error completely went away. Seems like a bug with Xcode or something.

Use of unresolved identifier - app development with Swift Project 2

Sorry - I realise this is a complete beginner question, but I've googled for half a day now and still can't resolve the issue myself.
I'm using xCode 8.3 and trying to complete the apple - app development with swift course - end of unit project 2. I'm told (by the Apple book) I should be able to run the app without build failures, even if it isn't finished.
I get an unresolved identifier error when I add the following code to my ViewControler file, inside the class ViewController: UIViewController.
func updateUI() {
correctWordLabel.text = game.formattedWord
scoreLabel.text = "Wins: \(totalWins), Losses: \(totalLosses)"
treeImageView.image = UIImage(named: "Tree \(currentGame.incorrectMovesRemaining)")
}
xCode suggests I change it to Game.formattedWord, but when i do get 'Instance member 'formattedWord' cannot be used on type 'Game' ViewController.Swift'.
Could someone please help?
I've checked the sample code from Apple about 100 times and they are def saying it should be game.formattedWord in the code.
Thank you!
Try correctWordLabel.text = currentGame.formattedWord
I think it’s a typo.
Earlier in your code you create an instance of the Game struct called currentGame so you are accessing the formattedWord variable inside that instance. That’s why you couldn’t change it to Game. Game is like the blueprint of the struct. currentGame is your actual ‘thing’ Hope that makes some sense.

ObjC class method is not called. GDB playing games?

I have a custom UITableViewController that I am trying to use to manage a UITableView. The flow of my code in the main UIViewController that contains the UITableView goes like below:
_messagesTableVC = [[AllMessagesTableViewController alloc] init];
_allMessageTableView.dataSource = _messagesTableVC;
_allMessageTableView.delegate = _messagesTableVC;
[_allMessageTableView reloadData];
The AllMessagesTableViewController custom UITableViewController class is initialized, it does any processing needed and I set the _allMessageTableView (the UITableView)'s delegates to my custom class.
When I run this code, the program acts as if the custom class is not there but no errors occur. It seems as that NO methods in the custom class are called, no init, no initWithCoder, nothing (I have set breakpoints and checked ;)).
As you can see in the screenshot below, I have set a breakpoint after a custom method refreshData in the custom class that I set to return YES. I assign the return value of refreshData to a local variable test.
In the debugger:
_messagesTableVC custom class does not appear to be nil.
test does not appear to exist.
Not shown here, but when I try to run [_messagesTableVC refreshData] in the debugger it says error: Execution was interrupted, reason: Attempted to dereference an invalid ObjC Object or send it an unrecognized selector.
The process has been returned to the state before expression evaluation.. So is _messagesTableVC actually nil??
What could be causing these problems or is GDB playing games? This is a Messages app extension in case that makes any difference. Thanks.
Update: Here is the code for the custom class init and refreshData
- (instancetype)init {
self = [super init];
if (!self)
return nil;
return self;
}
- (BOOL)refreshData {
return YES;
}
Update2: I created a blank working project and copy pasted the exact files into my original project (because it is an iMessage extension to a big iOS app). It turns out the Xcode is running the older build of the app even after I cleaned the project and changed the UITableView delegate to supply a different text.
I created a Messages Extension for the same project in the past and deleted the target while keeping the files in the project. When I re-added the Messages Extension to the project, Xcode kept running the older build of the app.
I fixed the issue with Xcode running an older version of the app by:
Clean All
Delete Messages Extension target from project
Backup existing Message Extension code to a directory outside the project. Then delete the Messages app group and directory from the project.
Delete the Messages Extension build scheme from project.
Delete project Derived Data directory.
Restart Xcode, create new Messages Extension target in project, and import saved code.

App stuck in splash screen on iOS 9 with no error

My app gets stuck on splash screen in iOS 9 both on iPhone and simulator. I can run it on iOS 8 or lower on device and simulator with no problem. My colleague working on the same app has exactly the same problem.
There is no error or anything, just hangs on splash screen. If I stop it on xcode and try to run it from the phone or simulator directly, it would run without any problem.
By the way, I don't see didFinishLaunchingWithOptions or willFinishLaunchingWithOptions getting called!
In your "answer" you include the code:
+(void)initialize
{
titles = #[NSLocalizedString(#"CODE", nil), NSLocalizedString(#"ERROR", nil), NSLocalizedString(#"TROUBLESHOOTING", nil)];
}
This is indeed the source of your issue. It's wise to be very careful when implementing +load or +initialize. #bbum has a great article on exactly that topic.
+initialize is invoked the first time the class (or category) is touched - when the class is initialized +initialize is called by the class loading mechanism. There is no guarantee of when in the class loading process this may happen, which is part of your problem.
In your case you are using NSLocalizedString - which under the hood can be fairly heavy. It has dependancies on several other classes (NSString, etc) and can potentially access the file system. As #bbum points out in his article, that can lead to serious trouble. In your case, this may be a nasty deadlock.
Move your titles = #[NSLocalizedString... line to a more appropriate place in your object, like an initializer, awakeAfterUsingCoder:, etc. and your immediate problem should be solved. After doing so you should check your entire codebase for instances where +initialize and +load are implemented and audit them to make sure those uses are in line with #bbum 's recommendations.
OK I found the problem. It sounds ridiculous though!!
I am using UITabBarController and inside the first controller I have a UITableViewController with a customised datasource class which would initiate a hard code table header and these headers are localised!!
+ (void)initialize {
titles = #[NSLocalizedString(#"CODE", nil), NSLocalizedString(#"ERROR", nil), NSLocalizedString(#"TROUBLESHOOTING", nil)];
}
After I traced the stacks, I realised the process gets stuck right there with no trace and error! I still don't know why!
So I came up with a workaround:
+ (void)initialize {
titles = #[#"Code",#"Error",#"Troubleshooting"];
}
And only retrieve the localised value when returning the text:
- (NSString *)titleAt:(NSInteger)index {
return NSLocalizedString(titles[index],nil);
}
I have both debug and release set to NO
You sure "any SDK" also has arm64?
Ok, I think I found the answer.
You have to specify arm64 in all "Valid Architectures".
If you don't specify arm64 or forget one the app won't start and stays on the splashscreen.
Just verified this.
Is this an Xcode 7 bug?

Resources