I created a brand new single view application and added one line to the viewDidLoad method of the ViewController.swift file:
override func viewDidLoad() {
super.viewDidLoad()
_ = NSLocale.current.description
}
The NSLocale.current.description line crashes in Xcode 9 with no stack trace (just a EXC_BAD_ACCESS code=EXC_I386_GPFLT error message). The same project runs fine in Xcode 8.3.3. Anyone have any ideas why this is happening?
Here is my simulator region settings:
Based on the stack trace, it looks like it's trying to treat description as an ObjC property rather than a Swift property. Based on the source code, this shouldn't be happening. It's likely a bug in the latest Swift compiler that is producing the Swift libraries because it crashes on an iOS 9 device as well.
Be sure to file a bug with Swift since this seems to be a language bug. I've verified that it is still broken in the latest Swift 4 toolchain. In the meantime, you can get the same behavior of description using your own extension by simply duplicating the intended implementation like I've shown here.
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// let brokenDescription = NSLocale.current.description
// let otherBrokenDescription = Locale.current.description
let objcDescription = (Locale.current as NSLocale).debugDescription //"<__NSCFLocale: 0x1c00dbc10> \'en_US\'}"
let myDescription = Locale.current.myDescription // "en_US (current)"
}
}
extension Locale {
private var _kindDescription : String {
if self == Locale.autoupdatingCurrent {
return "autoupdatingCurrent"
} else if self == Locale.current {
return "current"
} else {
return "fixed"
}
}
public var myDescription: String {
return "\(identifier) (\(_kindDescription))"
}
public var myDebugDescription : String {
return "\(identifier) (\(_kindDescription))"
}
}
This was a bug fixed in Xcode 9 Beta 5.
Related
I am trying to integrate built.io in iOS application using Xcode 9.1 and swift 4 but it failed due to ambiguous save call error, although I have only called this method once still it says ambiguous call. I am unable to identify the problem.
I referred this link to integrate sdk in iOS :
Code used is
import UIKit
import Contentstack
import BuiltIO
class ViewController: UIViewController {
func built(){
var builtApplication : BuiltApplication = Built.application(withAPIKey: "")
var pc : BuiltClass = builtApplication.class(withUID: "test")
var projectObject:BuiltObject = pc.object()
projectObject.save { (responseType, err) in //ambiguous error here on save call
if err != nil {
print("Err")
} else {
print("Success")
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
}
I have installed sdk in project using cocoapod. Below image contains application screenshot that shows error. I am using BuiltObject class object to call save method but when I jump into save method it takes me to method of BuiltKeyStore class, and I completely don't understand why? Please help, Thanks in advance 🙂
You need to pass completionBlock as a parameter instead of inline.
Try the below code which works fine for Swift 3.2 & 4,
let completionBlock:BuiltRequestCompletionHandler = { (responseType:BuiltResponseType, error:Error?) in
if error != nil {
print("Err")
} else {
print("Success")
}
}
projectObject.save(completionBlock)
Give it a try that should definitely work.
I "inherited" an iOS Xcode Project in Swift. I've never programmed in Swift or used Xcode before. I copied the project from one user account to another and checked it into a git repo.
Now I'm araid this (the copying, permissions ?) might be the cause for the App not being able to read its settings properly. Because UserDefaults.standard.string(forKey: "pref_Foo") returns nil although in the Settings.Bundle's Root.plist there's clearly a pref_Foo identifier.
The App has worked before, so I don't see where this suddenly comes from.
Since I'm not too familiar with XCode all I did up til now was debug into the Application to see that UserDefaults.standard.string(forKey: "pref_Foo") is nil.
How could I approach this problem?
Thank you!
EDIT: This is part of my code in ViewController.swift
override func viewDidLoad() {
super.viewDidLoad()
loadSettings()
...
}
func loadSettings()
{
if(UserDefaults.standard.object(forKey: "pref_Foo") == nil)
{
printf("Error")
}
}
You should use below code with validation, first delete app and install again. then use, you will get success.
var UserStatus:String {
get{
return UserDefaults.standard.object(forKey: "pref_Foo") as? String ?? "0"
}
set(status){
UserDefaults.standard.set(status, forKey: "pref_Foo")
UserDefaults.standard.synchronize()
}
}
Use of code is as below.
if (UserStatus == "pref_Foo"){
self.logoutSuccess()
} else {
self.loginSuccess()
}
Update or set value is so simple in one line code as given below.
UserStatus = "pref_Foo"
I started getting crash reports for the sort lamdba in the below code, the third line in the grey box below:
private func fixOverlaps(inout blocks: [TimeBlock], maxOverlaps: Int? = nil) {
blocks.sortInPlace { a,b in
if a.startTime < b.startTime {
return true
} else if a.startTime == b.startTime && a.endTime < b.endTime {
return true
}
return false
}
...
Note the crash does not occur on debug builds from XCode. Only the App Store and Ad Hoc archives will crash, and only when the length of the blocks list is in the hundreds.
I modified the code to this, and the problem went away:
private func fixOverlaps(inout blocks: [TimeBlock], maxOverlaps: Int? = nil) {
blocks = blocks.sort { a,b in
if a.startTime < b.startTime {
return true
} else if a.startTime == b.startTime && a.endTime < b.endTime {
return true
}
return false
}
...
Is there something I've missed about how to use inout or sortInPlace? I can try to do a demo of this. It's on multiple versions of iOS (8/9) and Swift 2.1.
EDIT--------------------
Ok here's a minimal version that crashes. Turns out the inout was a red herring. If you start a new single view project in XCode 7.1, you can replace the view controller with this:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
var blocks = [TimeBlock]()
for var i in 0...20 { //Works if you put in a small number like 8
let t = TimeBlock()
t.start = Int(arc4random_uniform(1000)) //Get some random numbers so the sort has to do some work
t.end = Int(arc4random_uniform(1000))
blocks.append(t)
}
blocks.sortInPlace { a,b in
if a.start > b.start {
return true
}
return false
}
print("done") //Gets here on debug, not release
}
class TimeBlock {
var start = 0
var end = 0
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
So run it in release, and you should see it prints "Done" if you end the loop at around 17 but crashes with 20. Exact number might be different for you.
Worked around this without loss of functionality by using self.list = self.list.sort() instead of self.list.sortInPlace().
This is a bug in Xcode 7.1 . Turning the swift compiler optimization level from fast to none fixed this problem for me.
This code looks correct. It sounds like you've run across a bug in the compiler, which is generally the case when you have a crash in release configuration but not debug. You can perhaps verify this by enabling optimizations in your debug build and testing to see if it generates the problem. Aside from your workaround, the only other thing you need to do is file a bug.
I logged a bug on bugs.swift.org about this earlier today and received a prompt response from one of the developers that this is indeed an issue with Xcode 7.1. He pointed out that its resolution is outlined in the Xcode 7.2 Release Notes:
A bug in the optimizer has been fixed that caused in-place sort on mutable collections to crash. (23081349)
So using Xcode 7.2 to compile should also fix the issue.
I started getting crash reports for the sort lamdba in the below code, the third line in the grey box below:
private func fixOverlaps(inout blocks: [TimeBlock], maxOverlaps: Int? = nil) {
blocks.sortInPlace { a,b in
if a.startTime < b.startTime {
return true
} else if a.startTime == b.startTime && a.endTime < b.endTime {
return true
}
return false
}
...
Note the crash does not occur on debug builds from XCode. Only the App Store and Ad Hoc archives will crash, and only when the length of the blocks list is in the hundreds.
I modified the code to this, and the problem went away:
private func fixOverlaps(inout blocks: [TimeBlock], maxOverlaps: Int? = nil) {
blocks = blocks.sort { a,b in
if a.startTime < b.startTime {
return true
} else if a.startTime == b.startTime && a.endTime < b.endTime {
return true
}
return false
}
...
Is there something I've missed about how to use inout or sortInPlace? I can try to do a demo of this. It's on multiple versions of iOS (8/9) and Swift 2.1.
EDIT--------------------
Ok here's a minimal version that crashes. Turns out the inout was a red herring. If you start a new single view project in XCode 7.1, you can replace the view controller with this:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
var blocks = [TimeBlock]()
for var i in 0...20 { //Works if you put in a small number like 8
let t = TimeBlock()
t.start = Int(arc4random_uniform(1000)) //Get some random numbers so the sort has to do some work
t.end = Int(arc4random_uniform(1000))
blocks.append(t)
}
blocks.sortInPlace { a,b in
if a.start > b.start {
return true
}
return false
}
print("done") //Gets here on debug, not release
}
class TimeBlock {
var start = 0
var end = 0
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
So run it in release, and you should see it prints "Done" if you end the loop at around 17 but crashes with 20. Exact number might be different for you.
Worked around this without loss of functionality by using self.list = self.list.sort() instead of self.list.sortInPlace().
This is a bug in Xcode 7.1 . Turning the swift compiler optimization level from fast to none fixed this problem for me.
This code looks correct. It sounds like you've run across a bug in the compiler, which is generally the case when you have a crash in release configuration but not debug. You can perhaps verify this by enabling optimizations in your debug build and testing to see if it generates the problem. Aside from your workaround, the only other thing you need to do is file a bug.
I logged a bug on bugs.swift.org about this earlier today and received a prompt response from one of the developers that this is indeed an issue with Xcode 7.1. He pointed out that its resolution is outlined in the Xcode 7.2 Release Notes:
A bug in the optimizer has been fixed that caused in-place sort on mutable collections to crash. (23081349)
So using Xcode 7.2 to compile should also fix the issue.
I am facing a problem which must be deep in iOS8 - or I have overseen some
obvious problem. Any help is welcome.
Description:
In have created a JobTableViewController, which is displaying a list of jobs (filenames) and their job status in a table as
label and detail label.
If the user selects one entry more details of this job are displayed in the next controllers and can be changed on the following pages. On the return
to this controller the job status should be updated and displayed in the detail label. I have tested the app in different simulators and it is working as expected.
But if I run the app on my iPhone, it crashes with
EXC_BAD_ACCESS(code 1, address =… ) // the address is changing on every run
while it is accessing m_jobListStatus. If have added a println() statement, which is printing fine. The app is always crashing on the second return to this controller.
class JobTableViewController: UITableViewController {
// some private vars here
private var m_jobListStatus = [String:String]()
override func viewDidLoad() {
…
if let s = m_defaults.dictionaryForKey(CONSTANTS.JOB_LIST_STATUS) as? [String:String] {
m_jobListStatus = s
}
}
…
// update the status in the table, save the status in the system defaults file and save the changes in file
override func viewDidAppear(animated: Bool) {
if let file = m_filename {
println("\nin ViewDidAppear m_jobListStatus = \(m_jobListStatus) , \(checkJobStatus(file)), \(file)")
self.m_jobListStatus[file] = checkJobStatus(file) // < < < < - - - - - - C r a s h is here
m_defaults.setObject(m_jobListStatus, forKey: CONSTANTS.JOB_LIST_STATUS)
tableView.reloadData()
var json = MeterReading.saveToJSON(m_readingList)
json?.writeToFile(CONSTANTS.DOCS_DIR + file, atomically: true)
m_filename = nil
}
}
…
}
The output of the println looks as expected:
in ViewDidAppear m_jobListStatus =
[Auftrag-2015-03-01_12.17.39.meters: In Bearbeitung,
Auftrag-2015-02-27_20.36.33.meters: Neu] , Neu,
Auftrag-2015-02-27_20.36.33.meters
in ViewDidAppear m_jobListStatus =
[Auftrag-2015-03-01_12.17.39.meters: In Bearbeitung,
Auftrag-2015-02-27_20.36.33.meters: Neu] , In Bearbeitung,
Auftrag-2015-03-01_12.17.39.meters
Any ideas?
Thanks in advance
Found the problem. It looks like that
NSUserDefaults.setObject(m_jobListStatus, forKey: CONSTANTS.JOB_LIST_STATUS)
is the cause. It looks like it is turning m_jobListStatus to immutable.