Swift: Downcast causes application to crash, why? - ios

I have following snippets of code where I have crash on some devices:
Crashed: com.apple.root.default-qos
EXC_BAD_ACCESS KERN_INVALID_ADDRESS at 0x00000000cbd
Code:
var obj:AnyObject = command.arguments[0] as AnyObject!
var theData:AnyObject = obj["getContactImagesByEmails"] as AnyObject!
if let contactImagesByEmails:AnyObject = obj["emails"]{
if contactImagesByEmails is Array<String>{
/*line 176*/ let array:Array<String> =
contactImagesByEmails as Array<String> // CRASH happens here
results = WmSqliteImagesModel.getInstance.getImagesByEmailAsWmContactImage(array) as Dictionary<String,AnyObject>
}
}
Full stack trace
Thread : Crashed: com.apple.root.default-qos
0 libswiftCore.dylib 0x0000000100559794 swift_unknownRetain + 32
1 MyApp 0x000000010017c8a0 MyApp.Plugin.(getContactImagesByEmails (MyApp.Plugin) -> (ObjectiveC.CDVInvokedUrlCommand) -> ()).(closure #1) (Plugin.swift:176)
2 MyApp 0x000000010017c8a0 MyApp.Plugin.(getContactImagesByEmails (MyApp.Plugin) -> (ObjectiveC.CDVInvokedUrlCommand) -> ()).(closure #1) (Plugin.swift:176)
3 MyApp 0x00000001001790b0 partial apply forwarder for reabstraction thunk helper from #callee_owned () -> (#unowned ()) to #callee_owned (#in ()) -> (#out ()) with unmangled suffix "125" (Plugin.swift:62)
4 MyApp 0x0000000100179120 partial apply forwarder for reabstraction thunk helper from #callee_owned (#in ()) -> (#out ()) to #callee_owned () -> (#unowned ()) with unmangled suffix "128" (Plugin.swift:62)
5 libdispatch.dylib 0x00000001937e13ac _dispatch_call_block_and_release + 24
6 libdispatch.dylib 0x00000001937e136c _dispatch_client_callout + 16
7 libdispatch.dylib 0x00000001937ed40c _dispatch_root_queue_drain + 1152
8 libdispatch.dylib 0x00000001937ee75c _dispatch_worker_thread3 + 108
9 libsystem_pthread.dylib 0x00000001939bd2e4 _pthread_wqthread + 816
The Plugin.swift:176 points to:
let array:Array<String> = contactImagesByEmails as Array<String>
Do I miss something? I think this code should be safe.
if contactImagesByEmails is Array<String> returns true, why contactImagesByEmails as Array<String> fails?
Please help,
[EDIT]
command has type of CDVInvokedUrlCommand
#interface CDVInvokedUrlCommand : NSObject {
NSString* _callbackId;
NSString* _className;
NSString* _methodName;
NSArray* _arguments;
}

I don't know if this can actually fixes the problem, but there's a bit of redundancy in the 2 ifs and the following let. It can simply be written as:
if let contactImagesByEmails = obj["emails"] as? Array<String> {
results = WmSqliteImagesModel.getInstance.getImagesByEmailAsWmContactImage(contactImagesByEmails) as Dictionary<String,AnyObject>
}
Moreover, it would be safer to combine optional binding and optional downcast when invoking getImagesByEmailAsWmContactImage
if let results = WmSqliteImagesModel.getInstance.getImagesByEmailAsWmContactImage(contactImagesByEmails) as? Dictionary<String,AnyObject> {
...
}
Last, are you sure getInstance is a property and not a method? Shouldn't it be:
if let results = WmSqliteImagesModel.getInstance().getImagesByEmailAsWmContactImage(contactImagesByEmails) as? Dictionary<String,AnyObject> {
...
}

Perhaps try an alternate approach to getting the casted value:
if let contactImagesByEmails = obj["emails"] as? [String] {
results = WmSqliteImagesModel.getInstance.getImagesByEmailAsWmContactImage(contactImagesByEmails) as Dictionary<String,AnyObject>
}
I also wonder if your crash is not from naming your variable "array" in your original code...

Simplify this step by step with fewer references to AnyObject (and certainly not AnyObject!). The compiler is probably letting through something that is illegal, because when you start pulling out AnyObject you're saying "I know exactly what I'm doing; don't check this."
You'd expect this code to be something like:
let obj = command.arguments[0]
if let contactImagesByEmails = obj["emails"] as? [String] {
results = WmSqliteImagesModel.getInstance.getImagesByEmailAsWmContactImage(array) as? [String: AnyObject]
}
In the end results would be a [String:AnyObject]?
The key point here is that you should get rid of as many references to AnyObject as you can, and you should use if-let-as? to determine if the types are what you expect.
The fact that command.arguments is filled with things of various types that you have to type-check is pretty dangerous and a sign of a serious design problem. If there really are several types in there, you should use an enum rather than type-checking against random things like [String:AnyObject]. That's what enums are explicitly for. (If this is bridging from ObjC; enums may not be possible here, but even in ObjC, the right answer is seldom to have an NSArray filled with heterogeneous types. You create a class there to hold them rather than an enum.)

Related

iOS Today Extension Crashing

We've added Today Extension to our app recently.
Its an extension with simple tableView to load data from our server, written in Swift.
But after the extension is online to our users, we've received lots of crash data from Crashlytics and also Apple is reporting same crash issue either.
However, we can't reproduce the crash, or even find the reason of crash, because is crashing on the widgetPerformUpdateWithCompletionHandler method which is called by the system.
Below is the detail of crash log, some information are replaced.
Crashed: com.apple.main-thread
0 MyAppWidget 0x100091d8c MyAppWidgetViewController.(widgetPerformUpdateWithCompletionHandler((NCUpdateResult) -> ()) -> ()).(closure #1) (MyAppWidgetViewController.swift)
1 MyAppKit 0x100603ab4 partial apply for thunk (PostService.swift)
2 MyAppKit 0x100626080 ServiceRequestPerfomer.(performRequest(A, complete : ([B]?, NSError?) -> ()?) -> ()).(closure #1) (ServiceRequestPerformer.swift:35)
3 MyAppKit 0x1006258d4 partial apply for ServiceRequestPerfomer.(performRequest(A, complete : ([B]?, NSError?) -> ()?) -> ()).(closure #1) (ServiceRequestPerformer.swift)
4 MyAppKit 0x100626b34 ServiceRequestPerfomer.((request in _3C50B415180DDC893FFCB75CD7EE7019)(A, complete : (response : Response?, error : NSError?) -> ()?) -> ()).(closure #1) (ServiceRequestPerformer.swift:144)
5 Moya 0x1004b7468 MoyaProvider.(requestNormal(A, queue : OS_dispatch_queue?, progress : (progress : ProgressResponse) -> ()?, completion : (result : Result<Response, Error>) -> ()) -> Cancellable).(closure #1).(closure #1) (Moya.swift:229)
6 Moya 0x1004b8968 MoyaProvider.((sendAlamofireRequest in _1A5616FEE5C423A992964CB19AABD52B)(Request, target : A, queue : OS_dispatch_queue?, progress : (progress : ProgressResponse) -> ()?, completion : (result : Result<Response, Error>) -> ()) -> CancellableToken).(closure #3) (Moya.swift)
7 Moya 0x1004b57b8 partial apply for MoyaProvider.((sendAlamofireRequest in _1A5616FEE5C423A992964CB19AABD52B)(Request, target : A, queue : OS_dispatch_queue?, progress : (progress : ProgressResponse) -> ()?, completion : (result : Result<Response, Error>) -> ()) -> CancellableToken).(closure #3) (Moya.swift)
8 Alamofire 0x1002cff64 Request.(response(queue : OS_dispatch_queue?, completionHandler : (NSURLRequest?, NSHTTPURLResponse?, NSData?, NSError?) -> ()) -> Self).(closure #1).(closure #1) (ResponseSerialization.swift)
9 libdispatch.dylib 0x1819e14bc _dispatch_call_block_and_release + 24
10 libdispatch.dylib 0x1819e147c _dispatch_client_callout + 16
11 libdispatch.dylib 0x1819e6b84 _dispatch_main_queue_callback_4CF + 1844
12 CoreFoundation 0x181f4cd50 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 12
13 CoreFoundation 0x181f4abb8 __CFRunLoopRun + 1628
14 CoreFoundation 0x181e74c50 CFRunLoopRunSpecific + 384
15 GraphicsServices 0x18375c088 GSEventRunModal + 180
16 UIKit 0x18715e088 UIApplicationMain + 204
17 libxpc.dylib 0x181c38ce0 _xpc_objc_main + 784
18 libxpc.dylib 0x181c3a9dc xpc_main + 200
19 Foundation 0x182a57d60 service_connection_handler + 170
20 PlugInKit 0x18929ac48 -[PKService run] + 544
21 PlugInKit 0x18929a8dc +[PKService main] + 56
22 PlugInKit 0x18929ac6c +[PKService _defaultRun:arguments:] + 20
23 libextension.dylib 0x18286a058 NSExtensionMain + 64
24 libdispatch.dylib 0x181a128b8 (Missing)
And the code of widgetPerformUpdateWithCompletionHandler
func widgetPerformUpdateWithCompletionHandler(completionHandler: ((NCUpdateResult) -> Void)) {
// Perform any setup necessary in order to update the view.
// If an error is encountered, use NCUpdateResult.Failed
// If there's no update required, use NCUpdateResult.NoData
// If there's an update, use NCUpdateResult.NewData
let options: [String: AnyObject] = [DCKPostPopularAttributeName : true.stringValue,
DCKPaginationLimitAttributeName : 5]
postService.posts(options: options) { (posts, error) in
let historyPosts = self.userDefaults.arrayForKey(MyAppWidgetViewController.WidgetPostReadIdentifier) as? [UInt]
if let historyPosts = historyPosts {
self.posts = posts!.filter({ (Post) -> Bool in
return !historyPosts.contains(Post.id)
})
} else {
self.posts = posts!
}
self.tableView.reloadData()
self.tableView.hidden = false;
self.loadingLabel?.hidden = true
self.activityIndicator?.stopAnimating()
let contentSize = self.tableView.contentSize
self.preferredContentSize = CGSizeMake(CGRectGetWidth(self.view.frame), contentSize.height);
self.loadMorePostsIfNeeded()
}
completionHandler(NCUpdateResult.NewData)
}
The strange thing is:
We haven't encountered the crash issue while we're using our Today Extension normally (It should show Unable to load if today extension crashes)
We didn't receive any issue from our users reporting that today extension isn't working.
We've found the same crash log on our device, but the today extension is working normally as 1. described. And also, the time of crash log recorded, I'm not using my phone!
So we're guessing it's a 「fake」crash, the crash is logged, but the extension didn't really crashed.
Does anybody facing the same issue?
Thank you!
Answering my own question,
#matt is right, Now I am calling the completionHandler only when data fetch task completes, instead of always call the completionHandler at the last of widgetPerformUpdateWithCompletionHandler method.
I didn't receive crashes anymore, the problem was solved!

Why does app crash at NSData getBytes?

NSData is extended to determine the file type:
extension NSData {
var dataType: String? {
// Ensure data length is at least 1 byte
guard self.length > 0 else { return nil }
// Get first byte
var c = [UInt8](count: 1, repeatedValue: 0)
self.getBytes(&c, length: 1)
// Identify data type
switch (c[0]) {
case 0xFF:
return "jpg"
case 0x89:
return "png"
case 0x47:
return "gif"
case 0x49, 0x4D:
return "tiff"
default:
return nil //unknown
}
}
}
The method above is called on a NSData object from image data that is fetched from a server.
dispatch_async(dispatch_get_global_queue(QOS_CLASS_BACKGROUND, 0)) {
do {
// Fetch image synchronously from server
let query = PFQuery(className: <...>)
let result = try query.getFirstObject()
guard
let imageObject = result.objectForKey(<...>) as? PFFile,
let imageData = try? imageObject.getData(),
let image = imageData.dataType == "gif" ? UIImage.animatedImageWithAnimatedGIFData(imageData) : UIImage(data: imageData)
else {
return
}
<...>
} catch (let error as NSError) {
<...>
}
}
However the app very rarely crashes at line self.getBytes:
What is the reason for this?
The buffer of getBytes is &c, an UnsafeMutablePointer - do I have to take any special memory considerations because of that?
Update
The crashes still occur with the following variation of the code:
// Get first byte
var c: UInt8 = 0;
self.getBytes(&c, length: 1)
Update
The crashes still occur with the following variation of the code:
// Get first byte
var c = [UInt8](count: 1, repeatedValue: 0)
c.withUnsafeMutableBufferPointer {
buffer in
getBytes(buffer.baseAddress, length: 1)
}
guard c.indices.contains(0) else { return nil }
I got the following crash and included the whole thread, maybe someone can spot a hint:
Thread 18 Crashed:
0 libsystem_platform.dylib 0x21a8e198 _platform_memmove$VARIANT$CortexA9 + 92
1 Foundation 0x22512923 __34-[_NSDispatchData getBytes:range:]_block_invoke + 176
2 libdispatch.dylib 0x218d238d _dispatch_data_apply + 82
3 libdispatch.dylib 0x218d4a51 dispatch_data_apply + 26
4 Foundation 0x22512865 -[_NSDispatchData getBytes:range:] + 86
5 Foundation 0x2267730b -[_NSDispatchData getBytes:length:] + 24
6 MyAppName 0x00079ba0 partial apply forwarder for (extension in MyAppName):__ObjC.NSData.(dataType.getter : Swift.String?).(closure #1) (NSData+Extension.swift:54)
7 MyAppName 0x00079c14 partial apply forwarder for reabstraction thunk helper from #callee_owned (#inout Swift.UnsafeMutableBufferPointer<Swift.UInt8>) -> (#unowned (), #error #owned Swift.ErrorType) to #callee_owned (#inout Swift.UnsafeMutableBufferPointer<Swift.UInt8>) -> (#out (), #error #owned Swift.ErrorType) (NSData+Extension.swift:0)
8 MyAppName 0x00079cb8 generic specialization <Swift.UInt8, ()> of Swift.Array.withUnsafeMutableBufferPointer <A> ((inout Swift.UnsafeMutableBufferPointer<A>) throws -> A1) throws -> A1 (NSData+Extension.swift:0)
9 MyAppName 0x00079a70 (extension in MyAppName):__ObjC.NSData.dataType.getter : Swift.String? (NSData+Extension.swift:55)
10 MyAppName 0x00079948 #objc (extension in MyAppName):__ObjC.NSData.dataType.getter : Swift.String? (NSData+Extension.swift:0)
11 MyAppName 0x000d2264 MyAppName.DataManager.(fetchImagesFromServer (MyAppName.ImageSet) -> ()).(closure #1) (DataManager.swift:1214)
12 libdispatch.dylib 0x218cd823 _dispatch_call_block_and_release + 8
13 libdispatch.dylib 0x218dc5e9 _dispatch_root_queue_drain + 1558
14 libdispatch.dylib 0x218dbfcd _dispatch_worker_thread3 + 94
15 libsystem_pthread.dylib 0x21a91b29 _pthread_wqthread + 1022
16 libsystem_pthread.dylib 0x21a91718 start_wqthread + 6
Update
The crashes still occur with the following variation of the code:
// Get first byte
var c = UnsafeMutablePointer<UInt8>.alloc(1)
defer { c.dealloc(1) }
self.getBytes(c, length: 1)
switch (c[0]) { ...
With the help of an Apple engineer (via a TSI ticket) the issue was finally identified.
All code permutations above for reading the first byte are valid and working.
The issue was that the NSData object was created when a file was fetched from a server using the Parse iOS SDK which stores the data in a temporary file with file protection key NSFileProtectionCompleteUntilFirstUserAuthentication.
The file protection key allows reading data of the NSData object only after the user unlocks the device once after reboot. Although the data is not readable before unlocking, the NSData object can be created and even the NSData.length property is accessible. However, attempting to read the data would throw an exception.
I changed the code and added a check if the protected data is available before attempting to read it with UIApplication.sharedApplication().protectedDataAvailable.
You may wonder why a file was fetched by the app before the device was even unlocked. The app was started by a remote user notification. That explains why the crash happened so rarely.
Learned 2 things:
Always check your file protection key
Apple technical support gave a super in-depth explanation and is worth the money
A Swift array is more like a C++ std::vector than a C array: it has other contents besides the array elements. You can't get a pointer to the first element using &c. You need to ask the array for a pointer to its elements, like this:
var c = [UInt8](count: 1, repeatedValue: 0)
c.withUnsafeMutableBufferPointer { buffer in
getBytes(buffer.baseAddress, length: 1)
}
For your particular case, it seems overkill to use an array, though. Why not just do:
var c: UInt8 = 0;
self.getBytes(&c, length: 1)

How to figure out what makes my iOS app crash (EXC_BREAKPOINT)?

How can I know where exactly did my app crash ?
I receive a lot of crash from my users but I can't reproduce the crash myself and the crash log does not indicate a specific line:
Thread : Crashed: com.apple.main-thread
0 myapp 0x22d1d4 specialized ItemType.init(coder : NSCoder) -> ItemType? (ItemType.swift)
1 myapp 0x22c72c #objc ItemType.init(coder : NSCoder) -> ItemType? (ItemType.swift)
2 EventKitUI 0x234734a5 (Missing)
3 EventKitUI 0x23479639 (Missing)
4 EventKitUI 0x234161db (Missing)
5 EventKitUI 0x234734a5 (Missing)
6 EventKitUI 0x234728d3 (Missing)
7 myapp 0x1e9df4 specialized Item.init(coder : NSCoder) -> Item? (Item.swift:162)
8 myapp 0x1db9b8 #objc Item.init(coder : NSCoder) -> Item? (Item.swift)
9 EventKitUI 0x234734a5 (Missing)
10 EventKitUI 0x234728d3 (Missing)
11 EventKitUI 0x23471bc7 (Missing)
12 myapp 0x26f370 savedSearchList.getLastItem() -> Item! (savedItemList.swift:71)
13 myapp 0x26c008 specialized MenuInitializerViewController.getSideMenuViewController() -> UIViewController (MenuInitializerViewController.swift:39)
14 myapp 0x18388c SharedAppDelegate.showMainInterface() -> () (SharedAppDelegate.swift:427)
15 myapp 0x18398c #objc SharedAppDelegate.showMainInterface() -> () (SharedAppDelegate.swift)
16 myapp 0x188a48 SharedAppDelegate.(retreiveFirstData(SharedAppDelegate) -> () -> ()).(closure #1) (SharedAppDelegate.swift:290)
17 myapp 0x2657a4 partial apply for UserAppData.(getFirstData(UserAppData) -> (() -> (), failure : (error : NSError) -> ()) -> ()).(closure #3) (UserAppData.swift:45)
18 myapp 0x263828 partial apply for thunk (UserAppData.swift)
19 myapp 0x268c28 UserAppData.(getDiffusionsGroup(UserAppData) -> (() -> (), failure : (error : NSError) -> ()) -> ()).(successBlock #1)(AFHTTPRequestOperation!, responseObject : AnyObject!)() (UserAppData.swift:788)
20 myapp 0x266684 partial apply for UserAppData.(getDiffusionsGroup(UserAppData) -> (() -> (), failure : (error : NSError) -> ()) -> ()).(successBlock #1)(AFHTTPRequestOperation!, responseObject : AnyObject!)() (UserAppData.swift)
21 libtzupdate.dylib 0x344ffe2f (Missing)
22 libtzupdate.dylib 0x344ffe1b (Missing)
23 libtzupdate.dylib 0x345046c9 (Missing)
24 CoreAudio 0x226dc535 (Missing)
25 CoreAudio 0x226daa2f (Missing)
26 CoreAudio 0x2262d0d9 (Missing)
27 CoreAudio 0x2262cecd (Missing)
28 GeoServices 0x2b9a2af9 (Missing)
29 UIKit 0x268b62dd UIApplicationMain + 144
30 myapp 0x10f2d4 main (AppDelegate.swift:16)
31 libtzupdate.dylib 0x34528873 (Missing)
I understand that it might come from ItemType unarchive initializer, but I don't see what could be wrong with it:
required convenience init?(coder aDecoder: NSCoder)
{
self.index = aDecoder.decodeIntegerForKey("index")
self.name = aDecoder.decodeObjectForKey("name") as! String
self.id = aDecoder.decodeObjectForKey("id") as! String
self.type = Type(rawValue: aDecoder.decodeIntegerForKey("type")) ?? .Default
}
Try adding a Exception breakpoint and/or Swift error breakpoint in
View->Navigator->Show Breakpoint Navigator
and then click the + icon on the bottom
I am not sure this is helping but these two lines are not very safe code
self.name = aDecoder.decodeObjectForKey("name") as! String
self.id = aDecoder.decodeObjectForKey("id") as! String
You are force casting the object as a String without checking if it has a value. ObjectsForKeys are nil by default until you set them the first time.
So these 2 lines can potentially cause a crash if you haven't set the object at least once. Try using the ?? nil coalescing operator to ensure this cannot happen.
self.name = aDecoder.decodeObjectForKey("name") as? String ?? self.name
self.id = aDecoder.decodeObjectForKey("id") as? String ?? self.id
Now you check if the object exits (as? String) and if it doesnt than it uses the default name/id (?? self.name)
I am not sure this is causing the crash but this should improve your code.
Your code to save the Enum seems alrite because you are using the ?? operator, so I dont think thats causing the issue.
You only need to do nil checks for ObjectsForKeys, because they are of type AnyObject and therefore dont know what object they actually are until set once, hence it could cause a nil crash.
Compare this to say BoolForKey where you dont have to do this because it knows you are dealing with boolean values and therefore it defaults to false automatically.
Also, you are doing the same thing I keep seeing here, which is not using constants for keys. This is just prone to typos.
Create a struct above your class
struct Key {
static let name = "Name"
static let id = "ID"
}
and than use the keys like so
...objectForKey(Key.name)
Hope this helps

How to read this ios symbolicated crash log?

Apple rejected an APP's new version and sent me back crash log, it's hard for me to find the problem even the crash log has been symbolicated in Xcode. From the following, I guess that something wrong in func getGameCenterScore at line 246? Does it tell more problems?
BTW, before calling the func GameCenterScore(), GKLocalPlayer.localPlayer().authenticated is checked, but network is not checked. I have to think it problem here. Any suggestion?
Thx.
Exception Type: EXC_BREAKPOINT (SIGTRAP)
Exception Codes: 0x0000000000000001, 0x0000000100054ef4
Triggered by Thread: 0
Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0 xoxo 0x0000000100054ef4 xoxo.ViewController.(getGameCenterScore (xoxo.ViewController) -> () -> Swift.Int).(closure #1) (ViewController.swift:246)
1 xoxo 0x00000001000546b0 partial apply forwarder for reabstraction thunk helper from #callee_owned (#in ([Swift.AnyObject]!, ObjectiveC.NSError!)) -> (#out ()) to #callee_owned (#owned [Swift.AnyObject]!, #owned ObjectiveC.NSError!) -> (#unowned ()) with unmangled suffix "315" (ViewController.swift:0)
2 xoxo 0x0000000100055110 reabstraction thunk helper from #callee_owned (#owned [Swift.AnyObject]!, #owned ObjectiveC.NSError!) -> (#unowned ()) to #callee_unowned #objc_block (#unowned ObjectiveC.NSArray!, #unowned ObjectiveC.NSError!) -> (#unowned ()) (ViewController.swift:0)
3 GameCenterFoundation 0x000000018e9de3a0 0x18e964000 + 500640
4 libdispatch.dylib 0x0000000197841990 0x197840000 + 6544
5 libdispatch.dylib 0x0000000197841950 0x197840000 + 6480
6 libdispatch.dylib 0x0000000197846208 0x197840000 + 25096
7 CoreFoundation 0x0000000185a877f4 0x1859a8000 + 915444
8 CoreFoundation 0x0000000185a8589c 0x1859a8000 + 907420
9 CoreFoundation 0x00000001859b12d0 0x1859a8000 + 37584
10 GraphicsServices 0x000000018f09f6f8 0x18f094000 + 46840
11 UIKit 0x000000018a576fa8 0x18a500000 + 487336
12 xoxo 0x00000001000636c0 main (AppDelegate.swift:12)
13 libdyld.dylib 0x000000019786ea04 0x19786c000 + 10756
func getGameCenterScore(){
var gameCenterScore = 0
let leaderBoardRequest = GKLeaderboard()
leaderBoardRequest.identifier = "XXXXXXXXXXXXX"
leaderBoardRequest.loadScoresWithCompletionHandler { (scores, error) -> Void in
if (error != nil) {
println("Error: \(error!.localizedDescription)")
} else if (scores != nil) {
let localPlayerScore = leaderBoardRequest.localPlayerScore
gameCenterScore = Int(localPlayerScore.value)
if self.saveData.stringForKey("topScore") == nil {
self.saveData.setValue(gameCenterScore, forKey: "topScore")
self.topScoreLabel.text = "\(gameCenterScore)"
}else{
if gameCenterScore > self.saveData.integerForKey("topScore"){
self.saveData.setValue(gameCenterScore, forKey: "topScore")
self.topScoreLabel.text = "\(gameCenterScore)" // line 246
}
}
}
}
}
Just went through he same thing. A binary rejection for my uploaded app. Finally, got it accepted. I found the line number much like you did. (I used textWrangler and compared the symbolicated text to the original crash. And there was only one line that it could have been. Much like your 216.)
Lines listed as swift:0 are after the crash causing line.
To Solve or eradicate the problem:
1) I found ghosts can linger in my swift code. Clean and rebuild. Try moving the code around.
2) Note that the line where the crash is listed as being may be off by a few lines. The line they listed for my app was a comment. The error was the code above and that code looked okay. I solved it by rewriting in a different way.
3) Look over your code very carefully.
if gameCenterScore > self.saveData.integerForKey("topScore"){`enter code here`
Would this crash if your gameCenterScore == topScore?

Swift: Cast from Interface type array to Object array crashes

I have got an array of objects that conform to an interface
interface SomeInterface{}
and a class that conforms to that interface
class SomeClass : NSObject, SomeInterface{}
Now, I create an array of SomeInterface objects
var myInterfaceObjects : SomeInterface[] = SomeInterface[]()
Then I would like to cast this array to a SomeClass object array
var someClassObjects : SomeClass[] = myInterfaceObjects as SomeClass[] //CRASH!
How can I downcast without a crash ?
fatal error: can't reinterpretCast values of different sizes
(lldb) bt
* thread #1: tid = 0x935ef, 0x001986b8 libswift_stdlib_core.dylib`Swift.reinterpretCast <A, B>(A) -> B + 220, queue = 'com.apple.main-thread', stop reason = EXC_BREAKPOINT (code=EXC_ARM_BREAKPOINT, subcode=0xe7ffdefe)
* frame #0: 0x001986b8 libswift_stdlib_core.dylib`Swift.reinterpretCast <A, B>(A) -> B + 220
frame #1: 0x001bebdc libswift_stdlib_core.dylib`Swift.ContiguousArrayBuffer.storesOnlyElementsOfType <A>(Swift.ContiguousArrayBuffer<A>)<B>(B.Type) -> Swift.Bool + 912
frame #2: 0x001bde08 libswift_stdlib_core.dylib`Swift._arrayCheckedDownCast <A, B>(Swift.Array<A>) -> Swift.Optional<Swift.Array<B>> + 292
frame #3: 0x00094c84 MyApp`MyApp.MyClass.(data=SomeInterface[]! at 0x27db0870, response=Foundation.NSHTTPURLResponse! at 0x27db086c, error=None, self=<unavailable>) -> (Swift.Bool) -> ()).(closure #1) + 428 at MyClass.swift:81
Sounds like a compiler bug, you should report it (as Kevin said in the comments)
For now you can try to work around it by casting the objects individually:
var someClassObjects : [SomeClass] = myInterfaceObjects.map { $0 as SomeClass }
edit: updated to the latest swift syntax. Also worth mentioning this bug may have been resolved in beta 3 or beta 4 – I haven't checked

Resources