Home Can I make it simpler turning an integer into a string in a specific format using Swift?
Reply: 4

Can I make it simpler turning an integer into a string in a specific format using Swift?

darkginger
1#
darkginger Published in 2018-01-13 06:47:59Z

In my audio app, I am playing audio using a progress slider bar -- in the UI, I want to show the amount of time the episode has played. Here's how I am doing that.

   @objc func updateSlider(){

        Slider.value = Float(audioPlayer.currentTime)

        func secondsToHoursMinutesSeconds (seconds : Int) -> (Int, Int, Int) {
            return (seconds / 3600, (seconds % 3600) / 60, (seconds % 3600) % 60)
        }

        let example = (Float(audioPlayer.currentTime))
        let myIntValue = Int(example)
        self.goneTime.text = String(Float(describing: myIntValue)

This code updates a label dynamically but it does it in the format of (Int, Int, Int) as specified. Example Output: (1, 5, 20) when I want 1:5:20.

I have tried to modify the format (Int / Int / Int) which is flagged as an error.

A workaround -- but an ugly one -- I found using this Swift 3 answer: using .replacingOccurrencesOf. From the documentation, it says you can replace one part of the string at a time.

So I change my code to:

 func secondsToHoursMinutesSeconds (seconds : Int) -> (Int, Int, Int) {
            return (seconds / 3600, (seconds % 3600) / 60, (seconds % 3600) % 60)
        }

    let example = (Float(audioPlayer.currentTime))
    let myIntValue = Int(example)

    let updated = secondsToHoursMinutesSeconds(seconds: myIntValue)

    let updated2 = String(describing: updated)

    let str2 = updated2.replacingOccurrences(of: ",", with: ":", options:
        NSString.CompareOptions.literal, range: nil)

    let str3 = str2.replacingOccurrences(of: "(", with: "", options:
        NSString.CompareOptions.literal, range: nil)

    self.goneTime.text = str3

This works ok but is there a best practice to simplify these types of modifications? New to Swift and learning.

Leo Dabus
2#
Leo Dabus Reply to 2018-01-13 07:27:30Z

AVAudioPlayer currentTime instance property returns a TimeInterval (Double). You should use DateComponentsFormatter and set unitsStyle to positional:

extension Formatter {
    static let positional: DateComponentsFormatter = {
        let formatter = DateComponentsFormatter()
        formatter.unitsStyle = .positional
        return formatter
    }()
}

Playground testing:

let seconds: TimeInterval = 3920
let display = Formatter.positional.string(from: seconds)   // "1:05:20"

Usage in your case:

goneTime.text = Formatter.positional.string(from: audioPlayer.currentTime)
Madhur
3#
Madhur Reply to 2018-01-13 06:51:56Z

In Swift you can simply use String InterPolation, to achieve whatever data result you want as follows:

For example :

let val1 = 10
let val2 = 20
let val3 = 30

let result = "\(val1) : \(val2) : \(val3)"
print(result) // it will give output: 10:20:30

Hope it helps!

Stepan Grigoryan
4#
Stepan Grigoryan Reply to 2018-01-13 06:58:30Z

You can do so with Swift Interpolation:

let time = (1, 5, 20)
let myString = "\(time.0):\(time.1):\(time.2)"
pacification
5#
pacification Reply to 2018-01-13 08:16:16Z

Just for fun, you can do this in functional way:

let time = [1, 5, 20]
let result = time.reduce("", { $0 + ($0.isEmpty ? "" : ":") + "\($1)" })
print(result) // "1:5:20"
You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.315273 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO