Converting Obj-C to Swift - objective-c

I'm having trouble converting this line to Swift:
(void)authenticateLayerWithUserID:(NSString *)userID completion:(void (^)(BOOL success, NSError * error))completion { }
Here's my line in Swift:
func authenticateLayerWithUserID(userID: NSString) {(success: Bool, error: NSError?) -> Void in }
Anyone have some insight into what I'm not doing correctly?

I would translate this kind of function in Swift with a "completion handler":
func authenticateLayerWithUserID(userID: NSString, completion: (success: Bool, error: NSError?) -> ()) {
if userID == "Jack" {
completion(success: true, error: nil)
}
}
And call it like this:
authenticateLayerWithUserID("Jack", { (success, error) in
println(success) // true
})
EDIT:
Following your comments, here's a new example within a class function, and with an "if else":
class MyClass {
class func authenticateLayerWithUserID(userID: NSString, completion: (success: Bool, error: NSError?) -> ()) {
if userID == "Jack" {
completion(success: true, error: nil)
} else {
completion(success: false, error: nil)
}
}
}
MyClass.authenticateLayerWithUserID("Jack", completion: { (success, error) in
println(success) // true
})
MyClass.authenticateLayerWithUserID("John", completion: { (success, error) in
println(success) // false
})

If you want to make a call to that method, it will look like this in Objective-C (I think you're using this:
[self authenticateLayerWithUserID:userIDString completion:^(BOOL success, NSError *error) {
if (!success) {
NSLog(#"Failed Authenticating Layer Client with error:%#", error);
}
}];
In Swift
var c: MyClass = MyClass()
c.authenticateLayerWithUserID("user", completion: { (boolean, error) -> Void in
})

Related

Core data: concurency conflict between save and fetch

These two function calls seem to be conflicting:
MagicalRecord.save({ (localContext) in
let items = NewsItem.staleNewsItems(in: localContext)
if ((items?.count)! > 0){
items?.forEach({ (item) in
if let object = item as? NSManagedObject {
object.mr_deleteEntity(in: localContext)
}
})
}
})
and
- (void) buildAndFetchFRCsInContext:(NSManagedObjectContext*)context {
self.newsItemsFRC = [self buildFetchResultsControllerForClass:[NewsItem class] sortedBy:#"id" withPredicate:nil inContext:context];
[context performBlock:^{
__unused NSDate* start = [NSDate date];
NSError* error;
[self.newsItemsFRC performFetch:&error]; // this line crashes
[self calculateAndBroadcastCounts];
}];
}
Is this save call thread safe? If so what could cause these two functions to cause each-other to crash?
The issue is I'm modifying the news items outside of the context they were created in. So to fix the issue I had to move the code to the main thread. I switched from using magical records save to just performBlockAndWait which is guaranteed to run on the calling thread:
private static func cleanUpNewsItems() -> Void {
let context = NSManagedObjectContext.mr_()
context.performAndWait {
var itemsToDelete = [NSManagedObject]()
if let items = NewsItem.staleNewsItems(in: context) {
items.forEach({ (item) in
itemsToDelete.append(item as! NSManagedObject)
})
}
for item in itemsToDelete {
context.delete(item)
}
do {
try context.save()
} catch let error as NSError {
print("Error While Deleting Note: \(error.userInfo)")
}
}
}

How to convert Objective-C code to Swift code - errorhandling ,iOS

I'm trying to convert this text to swift:
- (void)sendData:(NSData*)data
{
NSError *error;
GameKitHelper *gameKitHelper = [GameKitHelper sharedGameKitHelper];
BOOL success = [gameKitHelper.match
sendDataToAllPlayers:data
withDataMode:GKMatchSendDataReliable
error:&error];
if (!success) {
NSLog(#"Error sending data:%#", error.localizedDescription);
[self matchEnded];
}
}
Now I've gotten so far here:
func sendData(data: NSData) {
var error: NSError?
var gameKitHelper = GameKitHelper.sharedGameKitHelper()
var success = try! gameKitHelper.match.sendDataToAllPlayers(data, withDataMode: GKMatchSendDataReliable)
if !success {
print("Error sending data:\(error.localizedDescription)")
self.matchEnded()
}
}
But It's giving me an error at if (!succes) and I read on apples documentation that the objective-c version of .sendDataToAllPlayers() will return a bool but the swift version won't.
Apple Documentation - GKMatch
So how can I handle the error
The sendDataToAllPlayers function throws an exception if an error occurs. You need a catch block to handle it:
func sendData(data: NSData) {
var gameKitHelper = GameKitHelper.sharedGameKitHelper()
do {
try gameKitHelper.match.sendDataToAllPlayers(data, withDataMode: .Reliable)
}
catch let error as NSError {
print("Error sending data:\(error.localizedDescription)")
self.matchEnded()
}
}

objective-c change to swift

I do not know how to convert the following Objective-C code into swift. How should I do ?
Objective-c
if (operations) {
if ([operations isKindOfClass:[NSArray class]]) {
for (id <MyOperation> operation in operations) {
if (operation) {
[operation cancel];
}
}
} else if ([operations conformsToProtocol:#protocol(MyOperation)]){
[(id<MyOperation>) operations cancel];
}
[operationDictionary removeObjectForKey:key];
}
swift
if operations != nil {
// doto .......
}
Try this code:
if operations != nil {
// doto .......
if (operations?.isKindOfClass(NSArray) != nil){
for operation in operations as! [MyOperation]{
operation.cancle()
}
} else if operations?.conformsToProtocol(MyOperation){
(operations as MyOperation).cancle()
}
operationDictionary.removeObjectForKey(key)
}
I didn't test it so may be you have to make little bit changes into this code.
Hope this will help.
I usually don't help people with complete conversions, but...
if let operations: AnyObject = operations {
if operations is NSArray {
for operation in operations as! [MyOperation] {
operation.cancel()
}
}
else if let operation = operations as? MyOperation {
operation.cancel()
}
operationDictionary.removeObjectForKey(key)
}

How to get ["error"]["type"] from error.userInfo in Swift?

I am wondering how do we do this in Swift?
I am trying to convert the code below to Swift
FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:#"me" parameters:nil];
[request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
if (!error) {
// handle successful response
} else if ([[error userInfo][#"error"][#"type"] isEqualToString: #"OAuthException"]) { // Since the request failed, we can
NSLog(#"The facebook session error");
} else {
NSLog(#"Some other error: %#", error);
}
}];
Here is what I've done.
request.startWithCompletionHandler { (connection: FBSDKGraphRequestConnection!, result: AnyObject!, error: NSError!) -> Void in
if error == nil {
// handle successful response
}
else if error.userInfo["error"]["type"] == "OAuthException" {
//THIS LINE WONT COMPILE
}
else {
println("Some other error");
}
}
But I get a compile error that says could not find member 'subscript' on this line
error.userInfo["error"]["type"] == "OAuthException"
Any ideas please?
Try:
if (error.userInfo?["error"]?["type"] as? String) == "OAuthException" {
userInfo is an optional dictionary of type [NSObject: AnyObject]? so you'll need to unwrap it. Dictionary lookups always return an optional (because the key might not exist) so you have to unwrap it before accessing the key of the nested dictionary. Using a ? instead of ! is optional chaining and it will harmlessly result in nil if the "error" key doesn't exist (instead of crashing if you use a !). Finally, you'll need to cast the result to String (from AnyObject) in order to be able to compare it to "OAuthException".
How about breaking down the error and type as shown below?
else if let errorOAuthException: AnyObject = error.userInfo as? Dictionary<String, AnyObject>{
if errorOAuthException["error"] != nil {
if errorOAuthException["type"] as? String == "OAuthException" {
//Do something for me
}
}
}

How would this be converted from Obj-C to Swift?

I am trying to re-write an app in swift which is currently in Objective-C. How would I change this single line into Swift, as my current attempt does not prove correct
Tabata *tabata = [notification object];
Here is the entire function:
- (void)stateChanged:(NSNotification*)notification
{
if (enabled)
{
Tabata *tabata = [notification object];
switch (tabata.getState) {
case EXERCISE:
case RELAXATION:
[player play];
break;
default:
break;
}
}
}
And here is what I've converted into Swift:
func stateChanged(notifcation: NSNotification) {
if enabled {
var tabata: Tabata! = notification.object //error "Use of unresolved identifier 'notification'"
switch tabata.getState() {
case .EXERCISE: fallthrough
case .RELAXATION:
player.play()
break
default:
break
}
}
}
In Swift you have to downcast objects of type AnyObject rather then declare the type
var tabata = notification.object as! Tabata
func stateChanged(notification: NSNotification) {
if(enabled) {
var tabata: Tabata = notification.object as! Tabata
switch tabata.getState() {
case .EXERCISE:
fallthrough
case .RELAXATION:
player.play()
break
default:
break
}
}
}
Hope this helps!