I'm trying to update my project to work with Xcode 7.0 and after updating my Swift projects I'm getting an error that I don't understand on this line.
let jsonData:NSDictionary = NSJSONSerialization.JSONObjectWithData(urlData!, options:NSJSONReadingOptions.MutableContainers ) as! NSDictionary
The error is
"Call can throw, but it is not marked with 'try' and the error is not handled"
I'm also getting these two errors in my project files...
"linker command failed with exit code 1 (use -v to see invocation)"
and
"error: cannot parse the debug map for "/Users/MattFiler/Library/Developer/Xcode/DerivedData/ePlanner-cqwzlxqgpwaloubjgnzdlomjkfea/Build/Intermediates/SwiftMigration/ePlanner/Products/Debug-iphonesimulator/ePlannerTests.xctest/ePlannerTests": No such file or directory"
Try this code:
do {
let jsonData = try NSJSONSerialization.JSONObjectWithData(urlData!, options: .MutableContainers ) as! NSDictionary
// Use jsonData here
} catch {
print("Well something happened: \(error)")
}
You'll need the try keyword as NSJSONSerialization.JSONObjectWithData now throws an error if something failed since Swift 2. Throwing functions need to be marked with try or try!.
Also you'll need the do { ... } catch to catch any errors that may occur. This will catch the error and handle it.
You might want to read up on the changes in Swift 2 to understand why this happened. Also the WWDC videos will be very helpful.
You need to try and catch if it throws an error.
do {
let jsonData:NSDictionary = try NSJSONSerialization.JSONObjectWithData(urlData!, options:NSJSONReadingOptions.MutableContainers ) as! NSDictionary
//...
}
catch {
}
Related
My code:
let cgpurl = URL(string: "https://api.coingecko.com/api/v3/ping")!
let task = URLSession.shared.dataTask(with: cgpurl) { (Data, URLResponse, Error) in
if let data = Data, let string = String(data: data, encoding: .utf8) {
let CGPing = string } ; resume() }
The problem is with the 2nd use of "cgpurl". I've tried changing case to no effect. The error I'm getting is, "Cannot use instance member 'cgpurl' within property initializer; property initializers run before 'self' is available". Ok... but I can't even replace cgpurl with the actual link? Then I get the error message "Ambiguous reference to member 'dataTask(with:completionHandler:)'" I realize this release of swift was supposed to be "small" & just to "fix errors" but I've not been able to find any current documentation on this release. I'm using swift 4.2.1 with Xcode 10.1
This code was taken directly from a teaching manual for Swift 4.2
No, it wasn't. The code you have was never right, in Swift 4.2 or any other version of Swift. You have blindly copied and pasted perhaps, without looking at the overall context.
The problem is that the code, as you have it, is sitting "loose" at the top of your view controller or other class declaration, perhaps something along these lines:
class MyViewController : UIViewController {
let cgpurl = // ...
let task = // ...
}
That's wrong. The most basic rule of Swift programming is that executable code can exist only in a function. For example:
class MyViewController : UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let cgpurl = // ...
let task = // ...
}
}
That may not solve all your issues, but at least you'll get past the most basic mistake you're making and the "Cannot use instance member" compile error will go away.
I got the follow error when attempting to build a parse.com project via Xcode 7.0/Swift 2.0:
Is there a work around for this?
What's the Swift 2.0 equiv.?
You can either:
user.signUpInBackgroundWithBlock { (succeeded: ObjCBool, error: NSError?) -> Void in
// do something
}
Or
user.signUpInBackgroundWithBlock { succeeded, error in
// do something
}
--
Note, Xcode can show you the appropriate types. For example, if I start to type and then let code completion show me the method, I see something like:
If I then hit enter and select the block: PFBooleanResultBlock? and hit enter again, I'll see:
That shows me precisely what types those two parameters are.
user.signUpInBackgroundWithBlock {success, error in
if error == nil {
//
}
else{
//
}
}
Above works fine with no errors.
Updating to 2.0 with Xcode 7 Beta 4
I have this code block
do
{
try AVAudioSession.sharedInstance().setActive(true)
} catch let err as NSError
{
println("Dim background error")
}
And its giving me the error (on the try line)
Errors thrown from here are not handled.
Is this a compiler error or is there something I am missing in my syntax?
I checked the docs and my code 'looks' correct.
What types of errors can AVAudioSession.sharedInstance().setActive(true) throw?
If it can only throw NSErrors, then there's no need of specifying this when catching the error. You could simply write:
do {
try AVAudioSession.sharedInstance().setActive(true)
} catch {
print("Dim background error")
}
If you want to use the error in your catch-scope, you can still access it. Swift automatically binds the thrown error to error, which can be used:
catch {
// do something with `error`
}
If the method throws multiple types of errors, and you only want to deal with the ones that are NSErrors, you can conditionally bind them:
catch let specialError as NSError {
// do something with `specialError`
}
You must ensure though, that every thrown error is handled. So assuming that the method can also throw a RandomError (which I just made up now), you would have to write:
catch let randomError as RandomError {
// do something with `randomError`
}
...in addition to the catch of the NSError.
Or you could of course use the general case:
catch {
// do something with `error`
}
So I assume your problem can be solved by removing let err as NSError, from your catch-statement.
May be a compiler bug. Anyway try removing let err as NSError ; catch alone is enough if you want to catch all errors.
Also, with Swift 2 you should use print, not println.
The following code compiles without errors with XCode 7 Beta 4:
import AVFoundation
class X {
func y() {
do {
try AVAudioSession.sharedInstance().setActive(true)
} catch {
print("Dim background error \(error)")
}
}
}
check this code that will you get idea on try/catch :
enum ErrorMessages :ErrorType {
case ErrorDescription
}
do
{
try AVAudioSession.sharedInstance().setActive(true)
} catch ErrorMessages.ErrorDescription
{
println("Present the error description here")
}
Is this usage not correct? why? The file name I use is correct!
on the right side of the playground I would aspect to see the content of the txt file.
In terms of why this failed, you'd have to look at the error object and examine why it failed. You're catching the error, so look at it:
func read(path: String) throws {
do {
try NSString(contentsOfFile: path, encoding: NSUTF8StringEncoding)
} catch {
print("cannot read: \(error)")
}
}
That will tell you why it failed.
Having said all of that, this doesn't quite make sense: First, you're reading the contents of the path into the NSString, but discarding it. You presumably want to return this string or do something with it.
Second, read has been declared in such a way as to say that it throws error, but it doesn't really. It catches any error that might happen itself, but doesn't throw anything. You have to decide whether read will throw any errors it generates, or whether it will handle them without throwing any error, or both.
Assuming the caller was going to handle the error, you might just forego any do-try-catch construct in read altogether:
func read(path: String) throws -> NSString? {
return try NSString(contentsOfFile: path, encoding: NSUTF8StringEncoding)
}
Then you can let the caller catch any error that NSString threw. For example, you might catch the "not found" error:
do {
let string = try read(path)
// do something with string
} catch let error as NSError where error.domain == NSCocoaErrorDomain && error.code == NSCocoaError.FileReadNoSuchFileError.rawValue {
// not found handling here
} catch {
print(error)
}
If you really wanted read to not only catch the error, but also make sure it throws one as well, then you'd need to have to explicitly throw an error from its catch block. You can use this pattern using either your own ErrorType or just throwing the original error you just caught:
func read(path: String) throws -> NSString? {
var string: NSString?
do {
string = try NSString(contentsOfFile: path, encoding: NSUTF8StringEncoding)
} catch {
// do whatever special handling you want here
// but also throw error so caller is informed that there was an issue
throw error
}
return string
}
Frankly, I think the pattern outlined above is simpler, but given your code snippet, I thought I'd also illustrate this latter pattern, too, in case you needed something like that.
I am also learning, so I wrote a little demo. Hope it helps.
Can anyone shed any light as to why the following code would crash in the release version of an Xcode 6 build but not in the debug version ?
Can I cast this as something to try and prevent this
// Check if iCloud is enabled
if let currentToken = NSFileManager.defaultManager().ubiquityIdentityToken {
// The following line causes a crash in Release version
FLOG(" currentUbiquityIdentityToken is \(currentToken)")
EDIT:
More digging and the problem was caused by this code when the "DataModel" name had been changed to something else. I would have expected the "let modelURL = NSBundle." line to have thrown an exception but it does not. Seems it was just pure coincidence that the debugger was on the "FLOG(...)" line of code when the bad access exception gets thrown.
lazy var managedObjectModel: NSManagedObjectModel = {
// The managed object model for the application. This property is not optional. It is a fatal error for the application not to be able to find and load its model.
let modelURL = NSBundle.mainBundle().URLForResource("DataModel", withExtension: "momd")!
return NSManagedObjectModel(contentsOfURL: modelURL)!
}()