You might think: "another post about this error".
Yes, i've been looking into this forum before writing this question and unfortunately i couldn't find something that could help, or atleast i know that this error gets on when there is a var that is not bound.
However since im quite new into this, i'd like some help.
I'm following a guide to make a simple infinite side scroller game.
So far everything went good but then i encountered this "nill" error.
The guide itself does not have this error.
So i tought maybe it could be that i use a newer version of xCode or iphone simulation. But im pretty sure its not about that.
My codings so far:
import Foundation
class MainScene: CCNode {
weak var hero: CCSprite!
func didLoadFromCCB() {
userInteractionEnabled = true
}
override func touchesBegan(touch: CCTouch!, withEvent event: CCTouchEvent!) {
// This is the error line. I think it is caused by (applyImpulse(ccp(0, 400)) )
hero.physicsBody.applyImpulse(ccp(0, 400))
}
}
How can i simply fix this?
should i make a variable with applyImpulse?
I also tried to switch between CGPoint (ccp) and CCPackage, both didn't worked.
weak var hero: CCSprite!
This is incredibly dangerous and likely the cause of your problem. Besides using !, which is almost always to be avoided, this mixes it with weak. That means that if something else stops pointing to hero, this variable becomes an implicitly unwrapped nil. The next time you access it, you crash.
First, get rid of the !. If it needs to be weak, use ?. Beyond that, decide if it should really be strong. nothing you've shown here suggests that it should be weak.
I think the error code above can cause much confusion for new people because we don't know what is "optional" in swift 2.0 vs older versions of swift. For example I was getting the same error and could not tell where the problem was. What I found out is that I was making a call to a method using parenthesis () and in the same function I called the method without the parenthesis. This caused the error above. The () are an optional component that became optional with Swift 2.0 the way I understand it. You have to be consistent when calling the methods otherwise the compiler will throw the "Found nil error while unwrapping an optional value". Here is my code: The method I called inconsistently was NSDirectoryEnnumerationOptions(). This is corrected in the example I am sharing:
func listFilesWithFilter() -> [String]
{
NSFileManager().URLForDirectory(.DocumentDirectory, inDomain: .UserDomainMask, appropriateForURL: nil, create: true)
let musicUrl = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask).first!
do{
let fileList = try NSFileManager.defaultManager().contentsOfDirectoryAtURL(musicUrl,includingPropertiesForKeys: nil, options: NSDirectoryEnumerationOptions())
print(fileList)
} catch let error as NSError {
print(error.localizedDescription)
}
// filter for wav files
do {
let directoryUrls = try NSFileManager.defaultManager().contentsOfDirectoryAtURL(musicUrl, includingPropertiesForKeys: nil, options: NSDirectoryEnumerationOptions())
print(directoryUrls)
let wavFiles = directoryUrls.filter(){ $0.pathExtension == "wav"}.map{ $0.lastPathComponent}
print ("WavFiles:\n" + wavFiles.description)
} catch let error as NSError {
print(error.localizedDescription)
}
return wavFiles
}
Related
Before I updated to iOS 14 on my iPhone, this code was working perfectly. After, iOS 14 this is weirdly not running... it is very odd and I have not seen any solution online, additionally from my investigation, I have not been able to see any change.
This code is used in order to retrieve a videoURL for this video from the imported Camera Roll (I use import Photos...).
phResourceManager.writeData(for: resource.last!, toFile: newURL!, options: resourceRequestOptions) { (error) in
if error != nil {
print(error, "not c67omplted error?")
} else {
print("woah completedd 345?")
newUserTakenVideo.videoURL = newURL
print(newUserTakenVideo.videoURL, "<--?")
}
}
EDIT:
To be clear, it "does not run" means the compleition block never runs... as in it never even runs and gives an error, the compleition block simply never is called (nothing prints at least..)
And here is a print statement printing out all the values I pass in to the parameters:
phResourceManager:
<PHAssetResourceManager: 0x282d352c0>
resource.last:
Optional(<PHAssetResource: 0x28128bc00> {
type: video
uti: public.mpeg-4
filename: v07044090000bu6n1nhlp4leque7r720.mp4
asset: C97B45D3-7039-4626-BA3E-BCA67912A2A9/L0/001
locallyAvailable: YES
fileURL: file:///var/mobile/Media/DCIM/113APPLE/IMG_3404.MP4
width: 576
height: 1024
fileSize: 4664955
analysisType: unavailable
cplResourceType: Original
isCurrent: YES
})
newURL:
Optional(file:///var/mobile/Containers/Data/Application/E2792F47-142E-4601-8D5B-F549D03C9AFE/Documents/Untitled%2027228354.MP4)
resourceRequestOptions:
<PHAssetResourceRequestOptions: 0x28230d480>
Note: this is the decleration for the resource variable:
let resource = PHAssetResource.assetResources(for: (cell?.assetPH)!)
I have a solution to this! Swift 4+, tested on iOS 14!
I looked through using a PHAssetResourceRequest, but the file names were messed with in the process, and it generally didn't work with my sandbox. Then I also tried requesting a AVPlayerItem from the PHAsset but this too, did not work with sandboxing...
But then, I tried simply using PHAssetResourceManager.default().writeData(... and seemingly started working!
I tested a bit more and seemed to work, here is the full code:
let resource = PHAssetResource.assetResources(for: (cell?.assetPH)!)
let resourceRequestOptions = PHAssetResourceRequestOptions()
let newURL = ExistingMediaVC.newFileUrl
PHAssetResourceManager.default().writeData(for: resource.last!, toFile: newURL!, options: resourceRequestOptions) { (error) in
if error != nil {
print(error, "error")
} else {
print("good")
newUserTakenVideo.videoURL = newURL
}
}
It is quite simple!! Tell me if anything is not working, and note I still use the ExisitingMedia.fileURL variable you used in your original code as well :)
This is a part if code when error happens:
class func randomWord() -> TBWord {
let randomIndex = Int(arc4random_uniform(UInt32(TBAppSettings.wordsForCurrentGame.count)))
let word = TBAppSettings.wordsForCurrentGame[randomIndex]
TBAppSettings.wordsForCurrentGame.removeAtIndex(randomIndex)
MagicalRecord.saveWithBlock { context in
let word = TBWord.findWordWithIdentifier(word.identifier, inContext: context) //here error happens
word?.used = true
}
return word
}
How can I workaround this? I know about other questions about this problem, but they are not enough for me.
(Besides the fact that MagicalRecord is a big misunderstanding of how to use Core Data properly...)
Have you tried to run you code with -com.apple.CoreData.ConcurrencyDebug 1 as a launch argument? This smells like a threading problem.
I'm trying to update the code in my app after the update to XCode 7 and it looks like I'm going to have to go through a serious learning curve again just to catch up. What am I doing wrong in the code below?
Is if let still being used?
I am so not familiar with try/catch outside of C#. I don't know how to use it in the context of swift and it'd be great to find an easy to understand guide that doesn't assume that I ever knew Objective C or have ever come across this before.
Use this instead:
do {
let json = try NSJSONSerialization.JSONObjectWithData(...)
return json
} catch let error as NSError {
print("JSON Error: \(error.localizedDescription)")
}
You are calling a method that throws a Swift error and as such, it needs to be marked with try.
do
{
let json = try NSJSONSerializer.JSONObjectWithData(...)
return json
}
catch
{
// By default the catch clause defines the variable error as whatever ws thrown
print("Error is \(error)")
return nil
}
Is pretty much what you want.
In case of my understanding is
let result: AnyObject? = try! NSJSONSerialization.JSONObjectWithData(jsonData!, options: NSJSONReadingOptions.MutableContainers)
Recently, I have been working on an application. The goal of the application is to show you your last 10 photos taken in the Today view of the Notification Center, among other things. The application works perfectly in the iOS Simulator, but as soon as I put it on a real device for testing, it fails. It returns the error:
fatal error: Unexpected nil while unwrapping an Optional value
Typically this is very easy to fix since XCode highlights the code that returned nil and gives you the opportunity to fix it. In this case, none of my code gets highlighted. Instead, it highlights a line from Thread 1 (Is this the correct term? Thread 1?), as seen below:
Also note that above the highlited line is the line
; function signature specialization <Arg[0] = Exploded, Arg[1] = Exploded of Swift.(_fatalErrorMessage (Swift.StaticString, Swift.StaticString, Swift.StaticString, Swift.UInt) -> ()).(closure #2)
I included this line in the picture because of the "fatalErrorMessage" part of it. I suspect this could clue me in on the error, but I have no idea what this means. I'm not yet to the point of understanding that.
Also, after some thought, I placed a breakpoint at the viewDidLoad() function in the hopes of tracking any nil values, but the code appears to never even get to this point. It seems as if none of my code is being run.
Has anyone had problems like this/understands what that error code (If that's what it is) means? I'm pretty desperate now, hence me being here.
Thanks,
CodeIt
EDIT:
I placed a println line inside the viewDidLoad function to double check if it was being run. The println function runs and outputs correctly, so I think I may just have messed up my breakpoint somehow. Anyway - the code runs, but it still doesn't highlight any of my code causing the nil value.
EDIT 2:
As requested, I have inserted parts of my code. Please keep in mind that this code is a "first draft", if you will, and I have not yet gotten around to cleaning it up. I'm just trying to get it to work:
#IBOutlet weak var currentPosLabel: UILabel!
var currentImgPos = 0
#IBOutlet weak var imageView: UIImageView!
var images: NSMutableArray!
var totalImageCountNeeded: Int!
func fetchPhotos() {
images = NSMutableArray()
totalImageCountNeeded = 10
self.fetchPhotoAtIndexFromEnd(0)
}
func fetchPhotoAtIndexFromEnd(index: Int) {
let imgManager = PHImageManager.defaultManager()
var requestOptions = PHImageRequestOptions()
requestOptions.synchronous = true
var fetchOptions = PHFetchOptions()
fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
if let fetchResult = PHAsset.fetchAssetsWithMediaType(PHAssetMediaType.Image, options: fetchOptions) {
if fetchResult.count > 0 {
imgManager.requestImageForAsset(fetchResult.objectAtIndex(fetchResult.count - 1 - index) as? PHAsset, targetSize: view.frame.size, contentMode: PHImageContentMode.AspectFill, options: requestOptions, resultHandler: { (image, _) in
self.images.addObject(image)
if index + 1 < fetchResult.count && self.images.count < self.totalImageCountNeeded {
self.fetchPhotoAtIndexFromEnd(index + 1)
} else {
println("Completed array: \(self.images)")
}
})
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewDidAppear(animated: Bool) {
// NOTE: I am calling the fetchPhotos() function here since earlier in my debugging I thought the problem may be that I was calling it too early in the viewDidLoad function. It an incorrect theory, but it was worth a try.
fetchPhotos()
if images.count > 0 {
imageView.image = images[1] as? UIImage
}
}
I removed some parts of the code that I know have no reasons to cause my error, such as #IBActions, didReceiveMemoryWarning(), etc..
Even it's old question. I found my issue by deleting derived data from xcode.
Xcode -> window->Projects then select and delete your project derived data.
I don't think it is possible to determine exactly where the problem is without seeing your code.
Somewhere in your code you may have forced downcast a variable as!. If you change this to:
if let variable = optionalVariable as? SomeClass {
//Insert your code
}
Then this should fix your problem. Read this to learn more about casting in swift:
https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/TypeCasting.html
You should run the same device on simulator and real device.As an example if you run on 5s on real device then try the same device on simulator.By running simulator, it will definitely show the error.My error was the not connecting the #IBActions. Hope that this tip will help you.
I received the same error when trying to set a non-optional value to the value of an implicitly-unwrapped optional that was nil.
Ex. someGlobalFunction() returns an ImplicitlyUnwrappedOptional with a nil value then you try to set that to a regular value.
func someGlobalFunction() -> String! { return nil }
class MyClass {
let aVariable: String
init() {
aVariable = someGlobalFunction()
}
}
I am using a third-party framework which is written in Obj-C, it has a function :
- (NSError *)generateModelForm
If this method is successful it will return nil. If it doesn't return nil, it will return an error which you can check for debugging purposes.
Now when I call this function in my Swift file using bridging header and doing all required stuffs, it always crash on first line saying 'fatal error: unexpectedly found nil while unwrapping an Optional value'
My Swift code :
if let error = object.generateModelForm()
{
println("Error : \(error)")
}
else
{
println("Successfully generated model form, proceed ahead.")
}
I had gone through description given on this link. But its hardly helping me, since function I am using is a part of a pre-defined framework written in Obj-C.
I tried replacing first line with,
let error = object.generateModelForm() as NSError?
let error : NSError? = object.generateModelForm()
Also, even if try calling object.generateModelForm() directly, without capturing return NSError value, it still crashes.
I am scratching my head from last 2 days with it, Any help would be appreciated.
If 'object' is an optional, try object?.generateModelForm() ...with a '?'.
In case you have been using Swift 1.1 you should unwrap when executing that if let
if let error = object.generateModelForm()? {
//do stuff
}
Be aware that the if let only lets you do things if the constant variable that you are just creating for the scope inside the if-block is actually an unwrapped existing object. what you were trying to do is set an optional as a not-optional
Swift 1.2 (which is available as of today 9th of April 2015 with Xcode 6.3) you dont need to add that but in case you want to cast it as a NSError
if let error = object.generateModelForm() as? NSError {
//do stuff
}