Skip to content

Instantly share code, notes, and snippets.

@iGranDav
Last active April 26, 2024 02:21
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save iGranDav/8a507eb9314391338507 to your computer and use it in GitHub Desktop.
Save iGranDav/8a507eb9314391338507 to your computer and use it in GitHub Desktop.
import Foundation
extension UIDevice {
/**
Try to get the username from the device name using common knows
default device names format.
- copyright: Owen Godfrey on [StackOverflow](http://stackoverflow.com/questions/8261961/better-way-to-get-the-users-name-from-device)
- remark: Original regexpr improved to support custom name with model included eg. `<username>'s iPhone 6S`
- returns: Username found or the device name itself as default value
*/
func username() -> String {
let deviceName = self.name
let expression = "^(?:iPhone|phone|iPad|iPod)\\s+(?:de\\s+)?(?:[1-9]?S?\\s+)?|(\\S+?)(?:['']?s)?(?:\\s+(?:iPhone|phone|iPad|iPod)\\s+(?:[1-9]?S?\\s+)?)?$|(\\S+?)(?:['']?的)?(?:\\s*(?:iPhone|phone|iPad|iPod))?$|(\\S+)\\s+"
var username = deviceName
do {
let regex = try NSRegularExpression(pattern: expression, options: .CaseInsensitive)
let matches = regex.matchesInString(deviceName as String,
options: NSMatchingOptions.init(rawValue: 0),
range: NSMakeRange(0, deviceName.characters.count))
let rangeNotFound = NSMakeRange(NSNotFound, 0)
var nameParts = [String]()
for result in matches {
for i in 1..<result.numberOfRanges {
if !NSEqualRanges(result.rangeAtIndex(i), rangeNotFound) {
nameParts.append((deviceName as NSString).substringWithRange(result.rangeAtIndex(i)).capitalizedString)
}
}
}
if nameParts.count > 0 {
username = nameParts.joinWithSeparator(" ")
}
}
catch { NSLog("[Error] While searching for username from device name") }
return username
}
}
@jurgenizer
Copy link

Thank you, this is great!

@jtAcacia
Copy link

jtAcacia commented Jul 10, 2017

Swift 3 Implementation + Removing string after last punctuation component

extension UIDevice {
    var username:String {
        let deviceName = self.name
        let expression = "^(?:iPhone|phone|iPad|iPod)\\s+(?:de\\s+)?(?:[1-9]?S?\\s+)?|(\\S+?)(?:['']?s)?(?:\\s+(?:iPhone|phone|iPad|iPod)\\s+(?:[1-9]?S?\\s+)?)?$|(\\S+?)(?:['']?的)?(?:\\s*(?:iPhone|phone|iPad|iPod))?$|(\\S+)\\s+"
        
        var username = deviceName
        
        do {
            let regex = try NSRegularExpression(pattern: expression, options: .caseInsensitive)
            let matches = regex.matches(in: deviceName as String,
                                                options: NSRegularExpression.MatchingOptions.init(rawValue: 0),
                                                range: NSMakeRange(0, deviceName.characters.count))
            let rangeNotFound = NSMakeRange(NSNotFound, 0)
            
            var nameParts = [String]()
            for result in matches {
                for i in 1..<result.numberOfRanges {
                    if !NSEqualRanges(result.rangeAt(i), rangeNotFound) {
                        nameParts.append((deviceName as NSString).substring(with: result.rangeAt(i)).capitalized)
                    }
                }
            }
            
            if nameParts.count > 0 {
                username = nameParts.joined(separator: " ")
                username =   username.components(separatedBy: .punctuationCharacters).dropLast()
                    .joined()
                    .components(separatedBy: .whitespaces)
                    .filter{!$0.isEmpty}.joined()
            }
        }
        catch { NSLog("[Error] While searching for username from device name") }
        return username
    }
}

@wingovers
Copy link

Updated for Swift 5, Chinese, and broader language compatibility using a largely non-Regex approach and NameComponentsFormatter. https://gist.github.com/wingovers/5897dda804a8f2e6280ec52a79340a5e

@iGranDav
Copy link
Author

Thanks @wingovers for your work on this 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment