For some reason this line of code is crashing on pre iPhone 6 devices:
var friendMatch = newDict.objectForKey("is_match") as Int
The dictionary is generated from JSON that I receive from an endpoint. The JSON looks like this:
"is_match" = 1;
I've also tried:
var friendMatch: NSNumber = newDict.objectForKey("is_match") as NSNumber
And the app still crashes on that line. The crash log is unhelpful.
Any thoughts on why this is working on iPhone 6 and 6+, but not on older devices?
var friendMatch = newDict.objectForKey("is_match") as Int
You should not be casting unconditionally. Cast conditionally instead:
if let friendMatch = newDict.objectForKey("is_match") as? Int {
// ...
}
Now if the cast fails you won't crash.
Could you add some more code? It could be that you are not properly decoding the NSData JSON into a dictionary.
Also, use literal syntax, it is cleaner and easier to read.
newDict["is_match"]
If you are reading the JSON fine, then before casting it to anything, try adding a println to see the value inside it, or breakpoints.
println(newDict["is_match"])
Post Discussion edit:
Try:
var newInt = newDict["is_match"].toInt()
Related
I am working on an ancient iOS app for a program that runs off VB6. It is passing strings over in a non unicode format including Hebrew characters which once they are parsed are displayed as "àáðø ãøåøé"
I am assuming it is being encoded in Windows Hebrew.
I can't seem to find anything in the apple documentation that explains how to handle this case. And most searches bring up solutions in Swift, no Obj-C. I tried this:
NSString *hebrewPickup = [pickupText stringByApplyingTransform:NSStringTransformLatinToHebrew reverse:false];
But that just gave me this:
"ðø ַ̃øַ̊øֵ"
I am stumped.
EDIT: Based on JosefZ's comment I have tried to encode back using CP1252, but the issue is that CP1255 is not in the list of NSStringEncodings. But seems like it would solve my issue.
NSData *pickupdata = [pickupText dataUsingEncoding:NSWindowsCP1252StringEncoding];
NSString *convPick = [[NSString alloc] initWithData:pickupdata encoding:NSWindowsCP1254StringEncoding];
NSString *hebrewPickup = [convPick stringByApplyingTransform:NSStringTransformLatinToHebrew reverse:false];
Ok, if any poor soul ends up here, this is how I ended up fixing it. I needed to add some Swift into my Obj-C code. (If only I could magically just rebuild the whole project in Swift instead.)
Here is the info on that: https://developer.apple.com/documentation/swift/imported_c_and_objective-c_apis/importing_swift_into_objective-c
Making use of this Swift Package: https://github.com/Cosmo/ISO8859
I added the following code to a new swift file.
#objc class ConvertString: NSObject {
#objc func convertToHebrew(str:String) -> NSString {
let strData = str.data(using: .windowsCP1252);
let bytes: Data = strData!;
if let test = String(bytes, iso8859Encoding: ISO8859.part8) {
return test as NSString;
}
let test = "";
return test as NSString;
}
}
Then in the Obj-C project I was able to call it like so:
ConvertString *stringConverter = [ConvertString new];
NSString *pickupTextFixed = [stringConverter convertToHebrewWithStr:pickupText];
NSString *deliverTextFixed = [stringConverter convertToHebrewWithStr:deliverText];
I'm running into a compiler error when using the following code:
func saveImageToDisk() {
let imageData = UIImagePNGRepresentation(imageView.image!)!
let fileName = getDocumentsDirectory().appendingPathComponent("image.png")
imageData.writeToFile(fileName, atomically: true)
}
The error is: Value of type 'Data' has no member 'writeToFile'
Could this be a compiler error, or something I'm missing? Thanks
SE-0005 proposed a better translation of Objective-C APIs into Swift and that affected NSData (or just Data now). Instead of writeToFile you'll have to use write(to:options:) (or even just write(to:)). Here is the documentation for the updated method.
i don't understand why this code doesn't work, the detector is always nil with the CIDetectorTypeQRCode constant, everything work with CIDetectorTypeFace.
I Supect a bug from API of Apple. This a the official doc : Apple documentation
#IBAction func analyseTag(sender: AnyObject) {
var detector:CIDetector = CIDetector(ofType: CIDetectorTypeQRCode, context:nil, options:[CIDetectorAccuracy: CIDetectorAccuracyHigh])
var decode = ""
var ciImage:CIImage = CIImage(image: ImgChoosed.image)
var message:String = "";
let features = detector.featuresInImage(ciImage)
for feature in features as [CIQRCodeFeature] {
message += feature.messageString
}
if(message == "") {
println("nothing")
} else {
println("\(message)")
}
}
Have you a solution?
Thank in advance guy's
The code you provided can't have a nil detector because it's not an optional and the compiler would complain about several places in your code if it was.
If features is empty then you know it didn't find a QR code in your image. Try providing a better image or turning down the CIDetectorAccuracy.
If features isn't empty then your cast is failing.
Edit:
You can't pass a nil context in the constructor.
This happened to us as well. iPhone 4s doesn't return a CIDetector of type QRCode. The other types (rectangle, face) work though…
The same code works as expected on the iPhone 6. Haven't tested on a 5 or 5s yet.
But two weeks ago it was still working on the 4s, I believe. It was still on iOS 8 back then, I guess.
Make sure your ImgChoosed.image is not nil.
Change another input image for testing.
Try for feature in features as! [CIQRCodeFeature].
I found that using on a device resolved this issue. The simulator seemed to always return nil for me.
Just after implementing a method for saving a users email and password from login into NSUserDefaults. My app crashes when running on iPhone 5s, but not in simulator (works as supposed).
Error message is:
dyld: Symbol not found: __TWPVSs26AutoreleasingUnsafePointerSs8_Pointer
Referenced from: /private/var/mobile/Containers/Bundle/Application/76A645B8-3428-452F-AEA4-60BAF6C28819/AppName.app/AppName
Expected in: /private/var/mobile/Containers/Bundle/Application/76A645B8-3428-452F-AEA4-60BAF6C28819/AppName.app/Frameworks/libswift_stdlib_core.dylib
in /private/var/mobile/Containers/Bundle/Application/76A645B8-3428-452F-AEA4-60BAF6C28819/AppName.app/AppName
My NSUserDefaults code is this (don't think the rest matters):
let loggedIn = "yes"
let userDefaults = NSUserDefaults.standardUserDefaults()
userDefaults.setObject(email, forKey:"Email")
userDefaults.setObject(pw, forKey:"Password")
userDefaults.setObject(loggedIn, forKey: "LoggedIn")
userDefaults.synchronize()
This is set after user has entered email and password and the server has validated these and returned "ok".
In prepareForSegue I have this code:
let navigationController = segue.destinationViewController as UINavigationController
let vc = navigationController.viewControllers[0] as LoggedInViewController
// Gets email from saved data
let userDefaults = NSUserDefaults.standardUserDefaults()
let sendEmail: String = userDefaults.stringForKey("Email")
userDefaults.synchronize()
vc.email = sendEmail
Update:
I have gone through the crash logs and noticed this:
I dont really know how to read it but I noticed that exception code 0x0000000196442124 is at the bottom of my included image.
_dispatch_mach_msg_send + 1624
What does that mean? Does it help?
I have also marked all methods and stuff that has with NSUserDefaults (as seen above) as comments to see if they caused the problem. But the app crashes anyway..
Thanks in advance!
The error message says something about autoreleasing memory.
Do you have any ...Release() function calls within your swift code?
If so, comment them out and try again.
let sendEmail: String = userDefaults.stringForKey("Email")
for me swift is confused by lines like these and fails to correctly infer the type.
It performs ..... I don't what but it can't really get from anyobject! to string correctly
it crashes when it tries to work with sendEmail
see:
Get from AnyObject(NSString) to String
I am trying to port elements of the CoreAnimationText sample to Swift. I cannot figure out though, how to extract or downcast the elements of CTRun from an array, in order to pass them to functions that expect and act upon the Swift-ified CTRun type. I either get runtime errors or linking errors from the playground snippet below
import CoreText
import QuartzCore
let text = NSAttributedString(string: "hello")
var line: CTLine = CTLineCreateWithAttributedString(text)
var ctRuns:CFArray = CTLineGetGlyphRuns(line)
let nsRuns:Array<AnyObject> = ctRuns as NSArray
nsRuns.count // == 1
// Playground execution failed: error: error: Couldn't lookup symbols:_OBJC_CLASS_$_CTRun
let nsRun = nsRuns[0] as CTRun
nsRun.self
println(nsRun.self)
let anyRuns = nsRuns as AnyObject[]
// can't unwrap Optional null
let anyRun = anyRuns[0] as CTRun
anyRun.self
println(anyRun.self)
let cft:AnyObject = anyRuns[0]
// CTRun is not contstructable with AnyObject
let runGlyphCount = CTRunGetGlyphCount(CTRun(cft));
// Can't unwrap Optional.None
let concreteRuns = anyRuns as CTRun[]
let concreteRun = concreteRuns[0] as CTRun
concreteRun.self
println(concreteRun.self)
Any ideas - am I missing something obvious? From the WWDC sessions and interop guide, I am led to believe that "Swift just takes care of this".
According to dev forums, this functionality is implemented in 6.1.
All your sample lines compile without errors and work as expected in
the latest Xcode, 6.1 (6A1052c) .
Interoperability with CF objects is impoving. You may find another
issues, in such case it'd be reported as bug.