XCode 7 join is deprecated - xcode

I just downloaded the XCode 7 GM seed. It complains about the join method on String. How do I use joinWithSeparator instead of join?
//1
// Create an `NSCharacterSet` set which includes everything *but* the digits
let inverseSet = NSCharacterSet(charactersInString:"0123456789").invertedSet
//2
// At every character in this "inverseSet" contained in the string,
// split the string up into components which exclude the characters
// in this inverse set
let components = string.componentsSeparatedByCharactersInSet(inverseSet)
//3
// Rejoin these components
let filtered = "".join(components)

Soon after I figured it out, in case you are stuck on the same problem.
replace 3rd step with the line below
let filtered = components.joinWithSeparator("")

let inverseSet =
NSCharacterSet(charactersInString:"0123456789+").invertedSet
let components = string.componentsSeparatedByCharactersInSet(inverseSet)
//let filtered = join("", components)
let filtered = components.joinWithSeparator("") //swift2.0change

Related

Why some string in SwiftUI app are not localized

I use Export/Import localization functionality in Xcode 13.2.1 and it works more or less fine but some strings are not exported in xcloc file, for example texts from function below
func createInitialStepTypes(inContext context: NSManagedObjectContext) {
let names = ["NVA", "NEC", "VA"]
let nvaDesc = "Step with not added value (typically preparing of equipment, exception handling, etc.)."
let necDesc = "Necessary steps but still not adding value (typically system actions like login, manual data entry, etc.)."
let vaDesc = "Step with added value (typically material handling)."
let descs = [nvaDesc, necDesc, vaDesc]
let colors: [Color] = [Color.red, Color.orange, Color.green]
for (i, _) in names.enumerated() {
name = names[i]
desc = descs[i]
color = colors[i]
save(stepTypeID: nil, inContext: context)
}
}
Strings from other functions in the same class like e.g. this one
errMsg = "Step type \(stepType.name!) can't be deleted because it's being used."
are captured correctly. Any idea why?
Thanks.

Heartrate with no decimal places

Im doing a watch app for the Apple Watch in Xcode and the sample code from the Apple Developer site SpeedySloth: Creating a Workout has the HeartRate rounded to one decimal place, e.g. 61.0
How can I fix this?
case HKQuantityType.quantityType(forIdentifier: .heartRate):
/// - Tag: SetLabel
let heartRateUnit = HKUnit.count().unitDivided(by: HKUnit.minute())
let value = statistics.mostRecentQuantity()?.doubleValue(for: heartRateUnit)
let roundedValue = Double( round( 1 * value! ) / 1 )
label.setText("\(roundedValue) BPM")
I tried changing both the 1's in there to 0 but that gave me a 6.1 BPM or a 0.0 BPM
Thanks
A simple solution is to round to an integer and show the integer.
let value = // ... some Double ...
let s = String(Int(value.rounded(.toNearestOrAwayFromZero)))
label.setText(s + " BPM")
Properly, however, you should put formatting a string based on a number into the hands of a NumberFormatter. That's its job: to format a number.
let i = value.rounded(.toNearestOrAwayFromZero)
let nf = NumberFormatter()
nf.numberStyle = .none
let s = nf.string(from: i as NSNumber)!
// ... and now show the string

line spacing in dynamically created swift 3/xcode labels

I'm having an issue where I am getting a list of skills back from an api and I want them to stack one on top of the other in two different sections, a left column and a right column. It works well but if the skill is longer than the width of the label it drops to a new line with the same spacing as the rest of the labels. The skill Adobe Creative Suite looks like Adobe Creative as one and Suite as another. I would like Suite to be underneath Adobe Creative but much closer so you can tell it's all one skill.
My code is here:
lblLeft.text = ""
lblRight.text = ""
if let expertiseCount = helper.expertise {
for i in 0..<expertiseCount.count {
if i % 2 == 0 {
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineSpacing = 10
let attrString = NSMutableAttributedString(string: lblLeft.text! + "\(expertiseCount[i].name ?? "")\n")
attrString.addAttribute(NSParagraphStyleAttributeName, value:paragraphStyle, range: NSMakeRange(0, attrString.length))
lblLeft.attributedText = attrString
} else {
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineSpacing = 10
let attrString = NSMutableAttributedString(string: lblRight.text! + "\(expertiseCount[i].name ?? "")\n")
attrString.addAttribute(NSParagraphStyleAttributeName, value:paragraphStyle, range: NSMakeRange(0, attrString.length))
lblRight.attributedText = attrString
}
}
}
I've already tried line spacing and that just changes the size between all lines so the space between Adobe Creative and Suite takes on that change as well.
Try:
lblLeft.numberOfLines = 0
lblLeft.lineBreakMode = .byWordWrapping
lblLeft.sizeToFit()
By setting number of lines to zero and turning word wrapping on, the label will grow to the required number of lines. sizeToFit() should size it properly.

Copy/paste data validation in Google Spreadsheets

I feel a bit silly not being able to figure this out. So this is the data validation I have set up:
Cell Range: Journal!J2
Criteria: List from a range - Journal!W2:X2
Cell Range: Journal!M2
Criteria: List from a range - Journal!Y2:AA2
This is great in my first row. I create another row and I'd like it to update all of the '2' to '3'. The cell range updates correctly, but the criteria does not, and I can't figure out an easy solution other than going in and updating it manually.
I've tried copy/paste as well as paste special -> data validation.
I know something like $Y$2 would fix the row/col but that's the opposite of what I want. I guess I'm wanting to maintain the relative formula vs it being an absolute formula?
Indeed, the "list from a range" type of validation treats the reference to the list as absolute rather than relative. I know two workarounds:
Custom formula
Validation based on the custom formula
=not(isna(match(J2, W2:X2, 0)))
is equivalent to "value must be from the range W2:X2", and it will be copied down correctly, the reference to W2:X2 being relative.
Drawback: you don't get an in-cell dropdown list with custom formula validation.
Script
One can use an Apps Script to manage data validation rules. The following script sets data validation rules in each cell of the range J2:J100, where the value is required to be from W:X of the same row.
function validate() {
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getRange("J2:J100");
var valuesColumn = 23; // begins in W
var valuesLength = 2; // has length 2, so W:X
var firstRow = range.getRow();
for (var i = 0; i < range.getHeight(); i++) {
var rule = SpreadsheetApp.newDataValidation()
.requireValueInRange(sheet.getRange(firstRow + i, valuesColumn, 1, valuesLength), true)
.setAllowInvalid(false)
.build();
range.offset(i, 0, 1, 1).setDataValidation(rule);
}
}

Xcode 6.1.1 Swift returns "Optional("$1234.12")" with formatter

i'm just in playground trying to get this thing to work, but it doesn't want to work for me..
var total = 1234.1234
var formatter = NSNumberFormatter()
formatter.numberStyle = .CurrencyStyle
println("\(formatter.stringFromNumber(total))")
// Returns: "Optional("$1,234.12")" instead of just "$1,234.12"
I want to show just the formatted number to the user but the extra Optional bit keeps showing up.
Since you're just in playgrounds and are sure that the optional contains a value,
you can use forced unwrappping by adding an exclamation mark:
print("\(formatter.stringFromNumber(total)!)")

Resources