Nsinvocationoperation' Is Unavailable in Xcode 6.1

NSInvocationOperation' is unavailable in Xcode 6.1

As of Xcode 6.1, NSInvocation is disabled in Swift, therefore, NSInvocationOperation is disabled too. See this thread in Developer Forum

Because it's not type-safe or ARC-safe. Even in Objective-C it's very very easy to shoot yourself in the foot trying to use it, especially under ARC. Use closures/blocks instead.

You have to use NSBlockOperation in Swift.

or addOperationWithBlock to NSOperationQueue

queue.addOperationWithBlock { [weak self] in
self?.backgroundRun(self)
return
}

Xcode 6.1 Swift issue - 'init()' is unavailable: superseded by import of -[NSObject init]

I have same problem, one way I found to suppress the error is to explicitly cast it:

leftBay = BayNode() as BayNode

Core Motion not working in Xcode 7 Swift 2.0

Funny thing... I came here looking for answers to this very same question. ;)

As far as I can tell (I am no expert in Swift or XCode) the problem is that there is not enough time between instructions for core-motion to get the data: if you call manager.startAccelerometerUpdates() and then, after a while, ask for the accelerometerData, then you'll have no problem. If in my SpriteKit game I start accelerometer updates at the viewDidLoad method of a GameViewController and I ask for the accelerometer data at the didMoveToView method of a Scene, then I get the data. But if I start the accelerometer and ask for the data in the same method, then I get nothing (I get nothing also when I start the accelerometer right before a transition to other Scene and then ask for the data in the next Scene).

I don't know if this is normal or a bug, but at least I found a temporal solution: give core-motion as much time as possible before getting the data.

Using new features while supporting older iOS versions

There are several things wrong with the code.

  1. NSOperationQualityOfServiceUserInitiated is a native type (NSInteger) so you can't use it the way that you are in either line.
  2. The qualityOfService is a property of type NSQualityOfService. Your attempt to pass an argument to the qualityOfService method (getter method) makes no sense. If you are trying to set the quality of service, you need to call the setter but you can't use performSelector.

You want:

if ([self.operationQueue respondsToSelector:@selector(qualityOfService)]) {
self.operationQueue.qualityOfService = NSOperationQualityOfServiceUserInitiated;
} else {
//Other stuff not related to the scope of this question
}

This code will compile fine as long as your Base SDK is iOS 8.0 or later. The Deployment Target doesn't matter.

If you also want to build this code with Xcode 5 or earlier (a Base SDK of iOS 7 or earlier) then you need to wrap the code with the proper compiler directives to check for the Base SDK.

Get current dispatch queue?

You do have the option of "dispatch_get_current_queue()", however the iOS 6.1 SDK defines this API with these disclaimers:

"Recommended for debugging and logging purposes only:"

and

"This function is deprecated and will be removed in a future release.".

Here's another related question with some alternatives you can consider if you want code that's future-proof.

This application is modifying the autolayout engine from a background thread, which can lead to engine corruption and weird crashes

Do not change UI from anything but the main thread. While it may appear to work on some OS or devices and not others, it is bound to make your application unstable, and crash unpredictably.

If you must respond to a notification, which can happen in the background, then ensure UIKit invocation takes place on the main thread.

You at least have these 2 options:

Asynchronous Dispatch

Use GCD (Grand Central Dispatch) if your observer can be notified on any thread. You can listen and do work from any thread, and encapsulate UI changes in a dispatch_async:

dispatch_async(dispatch_get_main_queue()) {
// Do UI stuff here
}

When to use GCD? When you do not control who sends the notification. It can be the OS, a Cocoapod, embedded libraries, etc. Using GCD will woke anytime, every time. Downside: You find yourself re-scheduling the work.



Listen on Main Thread

Conveniently, you can specify on which thread you want the observer to be notified, at the time you are registering for notifications, using the queue parameter:

addObserverForName:@"notification"
object:nil
queue:[NSOperationQueue mainQueue]
usingBlock:^(NSNotification *note){
// Do UI stuff here
}

When to observe on main thread? When you are both registering and registered. Bu the time you respond to the notification, you are already where you need to be.



Post Notification On Main Thread

[self performSelectorOnMainThread:@selector(postNotification:) withObject:notification waitUntilDone:NO];

Hybrid solution which does not guarantee that the observer is only invoked from said method. It allows for lighter observer, at the cost less robust design. Only mentioned here as a solution you should probably avoid.

AFNetworking checking Availability

Actually contrary to what A-Live said Reachability IS a part of AFNetworking. It's implemented in AFHTTPClient.h here. You need the correct imports in your .pch file as discussed here in order to use it.

To use it you'll probably want to have a subclass of AFHTTPClient so you can use setReachabilityStatusChangeBlock defined here. Here's a simple example without using a subclass.

AFHTTPClient *client = [AFHTTPClient clientWithBaseURL:[NSURL URLWithString:@"http://google.com"]];
[client setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
if (status == AFNetworkReachabilityStatusNotReachable) {
// Not reachable
} else {
// Reachable
}

if (status == AFNetworkReachabilityStatusReachableViaWiFi) {
// On wifi
}
}];

If you don't like how this reachability setup works then I would recommend Tony Million's fork of Apple's Reachability. Simple example:

Reachability *reach = [Reachability reachabilityWithHostname:@"google.com"];
if ([reach isReachable]) {
// Reachable
if ([reach isReachableViaWiFi]) {
// On WiFi
}
} else {
// Isn't reachable

[reach setReachableBlock:^(Reachability *reachblock)
{
// Now reachable
}];

[reach setUnreachableBlock:^(Reachability*reach)
{
// Now unreachable
}];
}


Related Topics



Leave a reply



Submit