SWIFT2 : EXC_BAD_ACCESS down casting a class conforming to ErrorType - switch-statement

I have a simple Object hierarchy : RESTError with 2 attributes (httpCode and message), and 4 subclasses of it. One of the subclasses, RESTBusinessError has two additional fields.
I've simplified my code here below, but a RESTError variable (which is actually a RESTBusinessError) is used within a switch statement. Whenever I try to access the fields of the subclass, I've a EXC_BAD_ACCESS. Any idea ? this looks obvious, and in the debug area, I can see that all my variables have the expected values.
I have this issue ONLY in case RESTError conforms to the protocol ErrorType.
Any Idea ?
var tmpError:RESTError;
tmpError=RESTBusinessError(httpCode: 422, message: "error", businessCode: "003", businessMessage: "error");
switch tmpError {
case is RESTAuthorisationError:print("AUTH Error");
case let bError as RESTBusinessError:
let s1=bError.httpCode;
let s2=bError.message;
let s3=bError.businessCode; // <- This systematically fails.
let s4=bError.businessMessage;
print("OK \(s1) \(s2) \(s3) \(s4)");
default: print("default");
}
Object Hierarchy is here below :
public class RESTError : ErrorType{
var httpCode:Int
var message:String
init(httpCode:Int,message:String) {
self.httpCode=httpCode;
self.message=message;
}
}
class RESTAuthorisationError : RESTError {}
class RESTServerError : RESTError {}
class RESTOtherError : RESTError {}
public class RESTBusinessError : RESTError {
var businessCode:String
var businessMessage:String
init(httpCode:Int,message:String, businessCode:String, businessMessage:String) {
self.businessCode=businessCode;
self.businessMessage=businessMessage;
super.init(httpCode: httpCode, message: message);
}
}

check this example
import Foundation
func f() {
let queue = dispatch_queue_create("a", DISPATCH_QUEUE_CONCURRENT)
var i: Int! = 0
dispatch_async(queue) {
i = nil
}
usleep(200000)
print(i) // this is wrong
}
f() // debugger will stop here !!!!

Related

Count core data attributes that fulfill a certain condition (SwiftUI)

I have created a core data entity with the following attributes (from Item+CoreDataProperties.swift file):
extension Item {
#nonobjc public class func fetchRequest() -> NSFetchRequest<Item> {
return NSFetchRequest<Item>(entityName: "Item")
}
#NSManaged public var id: UUID?
#NSManaged public var likes: Int16
}
I am trying to return within ContentView a variable that shows the total number of Item that have more than 5 likes. What would be the best way to do this?
I've tried adding the following computed property, but it only checks whether the first item in the array fulfills the condition and I I'm not sure how to get it to loop over all of them.
#FetchRequest(entity: Item.entity(), sortDescriptors: [])
var item: FetchedResults<Item>
var likesCount:Int {
get {
if item[0].likes > 5 {
return 1
}
else {
return 0
}
}
}
I was also reading about a method called countForFetchRequest, but it seems to only be for detecting errors and I'm not sure it applies here.
Many thanks! Any help greatly appreciated.
Maybe something like this:
var countOfItems: Int {
getCount()
}
and then:
func getCount() -> Int {
var countOfItems: Int = 0
let context = PersistenceController.shared.container.viewContext
let itemFetchRequest: NSFetchRequest<Item> = Item.fetchRequest()
itemFetchRequest.predicate = NSPredicate(format: "likes > %d", 5)
do {
countOfItems = try context.count(for: itemFetchRequest)
print (countOfItems)
}
catch {
print (error)
}
return countOfItems
}

Overriding util.format affects util.(other)

Exploring NodeJS..
BaseClass.js:
const util = require("util");
class BaseClass {
constructor() {
this.util = util;
this.init();
}
init() {
console.log( util.format( "%s", "baseclass format" ) );
console.log( util.isArray( [1,2,3] ) );
util.log( "baseclass log" );
}
}
module.exports = BaseClass;
SubClass.js:
const BaseClass = require("./BaseClass");
class SubClass extends BaseClass {
constructor() {
super();
}
init() {
this.util.format = function() { return "subclass format"; }
this.util.isArray = function() { return "subclass isArray"; }
this.util.log = function() { console.log( "subclass log" ); }
super.init();
}
}
new SubClass();
Output (of node SubClass.js):
subclass format
subclass format
subclass format
Hmm. Comment out util.format override in SubClass.js:
// this.util.format = function() { return "subclass format"; }
Try again. Output (of node SubClass.js):
baseclass format
subclass isArray
subclass log
Can someone tell me why this is happening? I'd've guessed that isArray and log call format within the util module but I'm not sure where to look to verify this. node_modules/node/index.d.ts isn't really enlightening me.
Your intuition is correct. The easiest place to verify this is the docs for console.log (emphasis mine):
console.log([data][, ...args])
Added in: v0.1.100
data <any>
...args <any>
Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).
In the Node.js source you can see where this happens in lib/console.js (line 140).
In your code, this.util is a reference to the object returned by require('util'), so when you replace this.util.format you're replacing it for all code, not just the code inside your class.

Compare Strings in Swift unit test

How do you test whether two Strings are equal in a Swift unit test? I've tried the == operator but it doesn't recognize it:
import XCTest
#testable import MyProject
class MyProject: XCTestCase {
override func setUp() {
super.setUp()
// Put setup code here. This method is called before the invocation of each test method in the class.
}
override func tearDown() {
// Put teardown code here. This method is called after the invocation of each test method in the class.
super.tearDown()
}
func testExample() {
// This is an example of a functional test case.
// Use XCTAssert and related functions to verify your tests produce the correct results.
XCTAssertNil(nil, "This test works")
}
func toJSONTest() {
let currentLocation = deviceLocation(timestamp: "2015-11-02 16:32:15 +0000",latitude: "40.2736577695212",longitude: "-111.715408331498")
var MyProjectStatuses = [MyProjectStatus(id: "", currentLocation: currentLocation)]
let json = ""
XCTAssertTrue(json == "")
}
func testPerformanceExample() {
// This is an example of a performance test case.
self.measureBlock {
// Put the code you want to measure the time of here.
}
}
}
And the actual method being tested from MyProject.swift:
func toJSON ()->String{
var json = ""
json = "{\"myproject_status\":"
json = json + "{\"id\":\"" + self.Id + "\""
return json
}
This part:
XCTAssertTrue(json == "")
Throws:
Operator is not a known binary operator
The problem is that toJSONTest is not a test. Change the name to testToJSON.
This works fine on my machine:
func testToJSON() {
let json = ""
XCTAssertTrue(json == "")
}
The test runs, and passes. However, I would probably write it like this:
func testToJSON() {
let json = ""
XCTAssertEqual(json, "", "They are not equal")
}
Although this question is explicitly about how to compare two Strings in a Swift unit test, what's implicit in the question is how to compare two JSON Strings. I just wanted to point out that the right thing to do when comparing two JSON strings is to parse the JSON Strings to a Foundation object with the JSONSerialization class and then to compare the resulting Foundation objects. This approach takes care of the problem of the two JSON Strings having slightly different formatting or fields in a different order. So, for example, it's important that "{\"a\":1,\"b\":2}" and "{\"b\":2,\"a\":1}" are deemed to be equal because they are logically equal.
Here's a Swift function I put together which helps with this comparison:
class JSONAssert {
class func assertEquals(expected: String, actual: String) {
let expectedData = Data(expected.utf8)
let actualData = Data(actual.utf8)
let expectedObject: Any
let actualObject: Any
do {
expectedObject = try JSONSerialization.jsonObject(with: expectedData, options: [])
} catch {
XCTFail("Failed constructing a Foundation object from `expected` (i.e. \(expected)): \(error)")
return
}
do {
actualObject = try JSONSerialization.jsonObject(with: actualData, options: [])
} catch {
XCTFail("Failed constructing a Foundation object from `actual` (i.e. \(actual)): \(error)")
return
}
guard let expectedDictionary = expectedObject as? NSDictionary else {
XCTFail("Failed casting expected object (i.e. \(expectedObject)) to an NSDictionary")
return
}
guard let actualDictionary = actualObject as? NSDictionary else {
XCTFail("Failed casting actual object (i.e. \(actualObject)) to an NSDictionary")
return
}
XCTAssertEqual(expectedDictionary, actualDictionary)
}
}

How to update the value of a boolean variable in swift?

I've spent the past 3 days trying to figure this out. I can easily do what I want to do in Java but as soon as I try to do it in Swift, Xcode gives me a hard time.
In this case, I am trying to retrieve a boolean object from Parse that will tell me whether the user's email has been verified. For some reason, whenever I tell to code to check to see if the object is false, checkEmail is apparently nil. Also worth noting, if I println(checkEmail) right after var checkEmail = User["emailVerified"] as Bool I get the correct boolean value (true or false).
Its looks like as soon as the code leaves the query function, the value for checkEmail is lost.
Any ideas on what I'm doing wrong?
import UIKit
class RegisterEmail: UIViewController {
var checkEmail: Bool?
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func shouldPerformSegueWithIdentifier(identifier: String!, sender: AnyObject!) -> Bool {
if identifier == "passEmail" {
var query = PFUser.query()
query.getObjectInBackgroundWithId("vFu93HatwL") {
(User: PFObject!, error: NSError!) -> Void in
if error == nil {
NSLog("%#", User)
} else {
NSLog("%#", error)
}
let checkEmail = User["emailVerified"] as Bool
println(checkEmail) //I get the correct value here
}
println(checkEmail) //The value is lost here
if (checkEmail == false) {
let alert = UIAlertView()
alert.title = "Error"
alert.message = "The email you have provided has not been verified."
alert.addButtonWithTitle("Dismiss")
alert.show()
return false
}
else {
return true
}
}
// by default, transition
return true
}
}
You're not assigning the new value to the object property, you're assigning it to a local variable. Get rid of the let keyword, which declares a new local variable, in:
let checkEmail = User["emailVerified"] as Bool

How passing a protocol as parameter in Swift

In Objective-C, I know how passing a protocol as parameter:
- (void)MyMethod:(Protocol *)myparameter
But in Swift there is no more Protocol type.
How can I pass a protocol as parameter without knowing which is ?
In one of your comments you say:
"I want create a method which return an array of type of class which implements a desired protocol."
Have you tried something like the following:
//notice the use of #objc here
#objc protocol AlertProtocol
{
func getMyName()->String
}
class Class1 : AlertProtocol
{
let name = "Object 1"
func getMyName() -> String
{
return name
}
}
class Class2 : AlertProtocol
{
let name = "Object 2"
func getMyName() -> String
{
return name
}
}
//borrowing from and refactoring siLo's answer
func classesConformingToProtocol(proto:Protocol) -> [AnyClass]
{
let availableClasses : [AnyClass] = [ Class1.self, Class2.self ]
var conformingClasses = Array<AnyClass>()
for myClass : AnyClass in availableClasses
{
if myClass.conforms(to: proto)
{
conformingClasses.append(myClass)
}
}
return conformingClasses
}
Then use the above structure like this:
let classes = classesConformingToProtocol(AlertProtocol.self)
The tricky part that does the work is the "#objc" that exposes the protocol to the objective c runtime and allows us to pass any "Protocol Type" as a parameter.
Probably at some point in the future we will be able to do this in a "pure" Swift way.
Here is what I have tried:
#objc protocol Walker
{
func walk()
}
#objc protocol Runner
{
func run()
}
#objc class Zombie : Walker
{
func walk () { println("Brains...") }
}
#objc class Survivor : Runner
{
func run() { println("Aaaah, zombies!") }
}
func classesConformingToProtocol(proto:Protocol) -> AnyClass[]
{
let availableClasses : AnyClass[] = [ Zombie.self, Survivor.self ]
var conformingClasses = Array<AnyClass>()
for myClass : AnyClass in availableClasses
{
if myClass.conformsToProtocol(proto)
{
conformingClasses.append(myClass)
}
}
return conformingClasses
}
// This does not work
let walkers = classesConformingToProtocol(Walker.self)
let runners = classesConformingToProtocol(Runner.self)
I have been unable to convert Swift's Metatype information into a Protocol object.
In swift 2.0, I use it like this before:
classA.conformsToProtocol(XXXProtocol.self as! Protocol)
It doesn't works fine...
Look the definition of Protocol:
// All methods of class Protocol are unavailable.
// Use the functions in objc/runtime.h instead.
#available(iOS 2.0, *)
public class Protocol {
}
All are unavailable...and I don't know which to use instead in objc/runtime.h
So I have to use this method:
if ClassA is protocol<XXXProtocol> {
// do something
}
Currently, it works...
If you don't allow use #objc (because yours protocols have property, for example), the only solution that I found is with closure. Then, you need use a closure to use a protocol and return a value.
protocol Proto { }
protocol Proto2 { }
class Foo: Proto { }
class Bar: Proto, Proto2 { }
class Baz: Proto2 { }
class Qux { }
func printConforms(classList: [AnyClass], protoCond: (AnyClass) -> Any?) {
for i in classList {
print(i, terminator: " -> ")
if protoCond(i) != nil {
print("is subscriber")
} else {
print("NOT IS subscriber")
}
}
}
let myClasses: [AnyClass] = [Foo.self, Bar.self, Baz.self, Qux.self]
printConforms(classList: myClasses, protoCond: { $0 as? Proto.Type })
More complete example: https://gist.github.com/brunomacabeusbr/eea343bb9119b96eed3393e41dcda0c9
Edit
Another better solution is using generics, for example:
protocol Proto { }
class Foo: Proto { }
class Bar: Proto { }
class Baz { }
func filter<T>(classes: [AnyClass], byConformanceTo: T.Type) -> [AnyClass] {
return classes.filter { $0 is T }
}
filter(classes: [Foo.self, Bar.self, Baz.self], byConformanceTo: Proto.Type.self)
// return [Foo.self, Bar.self]
Worked out a way today (Xcode 6.1):
Firstly, the protocol must be marked as #objc for any checking to work.
Then use an "if let" cast to check for conformance.
#objc protocol MyProtocol {
var protocolValue: Int { get set }
}
if let conformingObject = someObject as? MyProtocol {
// conformingObject is now someObject cast to MyProtocol
conformingObject.protocolValue = 3
}

Resources