Лучший способ получить имя пользователя с устройства? - PullRequest
13 голосов
/ 25 ноября 2011

Я сделал функцию, которая извлекает имя пользователя из имени устройства.

Идея состоит в том, чтобы пропустить шаги настройки, чтобы позволить пользователю сразу перейти к игре при первом запуске приложения.

Это неоптимальный подход , так как я никогда не могу доверять имени устройства для хранения имени пользователя. Вопрос: Как лучше это сделать?

Моя функция ниже получает правильное имя ...

  • ... если имя устройства по умолчанию не изменилось («iPod от Sanna»)
  • ... на английском языке,
  • ... на французском и аналогичных («iPod de Sanna»)
  • ... на шведском языке и аналогичных («Sannas iPod»), если имя не заканчивается на S («Johannes iPod» => возвращает «Johanne», но скорее должно вернуть «Johannes», чтобы оно было правильным, как само имя) оканчивается на S.)

Очевидно, что имя не будет правильно, если пользователь изменил имя устройства на другое, чем форма по умолчанию.

- (NSString *) extractPlayerNameFromDeviceName: (NSString *) deviceName  {

    // get words in device name
    NSArray *words = [deviceName componentsSeparatedByString:@" "];
    NSMutableArray *substrings = [[NSMutableArray alloc] init]; 
    for (NSString *word in words) {
        NSArray *subwords = [word componentsSeparatedByString:@"'"];
        [substrings addObjectsFromArray:subwords];
    }

    // find the name part of the device name
    NSString *playerName = [NSString stringWithString: @""];
    for (NSString *word in substrings) {
        if ([word compare:@"iPhone"] != 0
            && [word compare:@"iPod"] != 0
            && [word compare:@"iPad"] != 0
            && [word length] > 2) {
            playerName = word;
        }
    }

    // remove genitive
    unichar lastChar = [playerName characterAtIndex:[playerName length] - 1];
    if (lastChar == 's') {
        playerName = [playerName substringToIndex:[playerName length] - 1];
    }
    lastChar = [playerName characterAtIndex:[playerName length] - 1];
    if (lastChar == '\'') {
        playerName = [playerName substringToIndex:[playerName length] - 1];
    }
    return playerName;
}

Я использую его для предложения имени пользователя в моем приложении. Таким образом, большинству пользователей не придется писать свои имена пользователей.

Мое приложение не подключено к каким-либо другим службам, таким как iTunes или Facebook, но каждому пользователю требуется имя пользователя. Так как я могу получить имя?

Ответы [ 5 ]

8 голосов
/ 30 октября 2013

Я хотел бы предложить улучшение ответа Рики Хелегессона.Он имеет следующие особенности:

  • Он немного меньше, хотя и менее эффективен, поскольку использует регулярные выражения, но тогда я полагаю, его следует вызывать только один раз.
  • Я потратилон включает «телефон», а также «iPod», «iPhone» и «iPad».
  • Он удаляет «s» только тогда, когда ему непосредственно предшествуют «iPad», «iPhone» и т. д., но тольков конце строки.
  • Удаляет «iPad» и т. д., когда они являются первым словом, как в «iPad Simulator».
  • Прописывает первую букву каждого слова.
  • Это без учета регистра.
  • Это функция, потому что она не имеет зависимостей.

Вот код:

NSArray * nameFromDeviceName(NSString * deviceName)
{
    NSError * error;
    static NSString * expression = (@"^(?:iPhone|phone|iPad|iPod)\\s+(?:de\\s+)?|"
                                    "(\\S+?)(?:['’]?s)?(?:\\s+(?:iPhone|phone|iPad|iPod))?$|"
                                    "(\\S+?)(?:['’]?的)?(?:\\s*(?:iPhone|phone|iPad|iPod))?$|"
                                    "(\\S+)\\s+");
    static NSRange RangeNotFound = (NSRange){.location=NSNotFound, .length=0};
    NSRegularExpression * regex = [NSRegularExpression regularExpressionWithPattern:expression
                                                                            options:(NSRegularExpressionCaseInsensitive)
                                                                              error:&error];
    NSMutableArray * name = [NSMutableArray new];
    for (NSTextCheckingResult * result in [regex matchesInString:deviceName
                                                         options:0
                                                           range:NSMakeRange(0, deviceName.length)]) {
        for (int i = 1; i < result.numberOfRanges; i++) {
            if (! NSEqualRanges([result rangeAtIndex:i], RangeNotFound)) {
                [name addObject:[deviceName substringWithRange:[result rangeAtIndex:i]].capitalizedString];
            }
        }
    }
    return name;
}

Чтобы использовать это для возврата имени;

NSString* name = [nameFromDeviceName(UIDevice.currentDevice.name) componentsJoinedByString:@" "];

Это несколько сложно, поэтому я объясню;

  1. Регулярное выражение содержит три части;
    1. В начале строки сопоставьте, но не возвращайте «iPhone», «iPod», «iPad» или «phone» и необязательное слово «de».
    2. Atконец строки, сопоставьте и верните слово, за которым следуют и необязательные «s» (которые не возвращаются), а затем «iPad», «iPhone», «iPod» или «телефон» (которые также не возвращаются).
    3. Это совпадение совпадает с предыдущим, но оно должно работать для китайских имен устройств.(Адаптировано из сообщения Трэвиса Червя. Пожалуйста, скажите мне, если это не так.)
    4. Подберите и верните любое слово, которое не соответствует предыдущим правилам.
  2. Итерируйте по всемсовпадения, используйте их заглавные буквы и добавьте их в массив.
  3. Верните массив.

Если имя оканчивается на "s" без апострофа перед "iPad" и т. д., яне пытайтесь изменить его, потому что нет надежного способа выяснить, является ли "s" частью имени или множественным числом имени.

Наслаждайтесь!

4 голосов
/ 07 февраля 2012

Вот альтернатива, которая получает все имена.Кроме того, он не удаляет «s» в конце языков, которые используют «de» или «s».Кроме того, она заглавная первая буква каждого имени.

Реализация метода:

- (NSArray*) newNamesFromDeviceName: (NSString *) deviceName
{
    NSCharacterSet* characterSet = [NSCharacterSet characterSetWithCharactersInString:@" '’\\"];
    NSArray* words = [deviceName componentsSeparatedByCharactersInSet:characterSet];
    NSMutableArray* names = [[NSMutableArray alloc] init];

    bool foundShortWord = false;
    for (NSString *word in words)
    {
        if ([word length] <= 2)
            foundShortWord = true;
        if ([word compare:@"iPhone"] != 0 && [word compare:@"iPod"] != 0 && [word compare:@"iPad"] != 0 && [word length] > 2)
        {
            word = [word stringByReplacingCharactersInRange:NSMakeRange(0,1) withString:[[word substringToIndex:1] uppercaseString]];
            [names addObject:word];
        }
    }
    if (!foundShortWord && [names count] > 1)
    {
        int lastNameIndex = [names count] - 1;
        NSString* name = [names objectAtIndex:lastNameIndex];
        unichar lastChar = [name characterAtIndex:[name length] - 1];
        if (lastChar == 's')
        {
            [names replaceObjectAtIndex:lastNameIndex withObject:[name substringToIndex:[name length] - 1]];
        }
    }
    return names;
}

Использование:

// Add default values for first name and last name
NSString* deviceName = [[UIDevice currentDevice] name];
NSArray* names = [self newNamesFromDeviceName:deviceName];
// This example sets the first and second names as the text property for some text boxes.
[self.txtFirstName setText:[names objectAtIndex:0]];
[self.txtLastName setText:[names objectAtIndex:1]];
[names release];
3 голосов
/ 05 февраля 2016

Я преобразовал оригинальный Owen Godfrey ответ в Swift и обновил Regexpr, чтобы поддерживать больше шаблонов, таких как User's iPhone 6S или iPhone 5 de User ...

Я создал Gist здесь: https://gist.github.com/iGranDav/8a507eb9314391338507

extension UIDevice {

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
}
}
1 голос
/ 25 ноября 2011

Если он предназначен только для iPod и iPhone, то зачем вообще использовать имя пользователя?Если вам необходимо идентифицировать устройство для вашего веб-сервиса, существуют другие уникальные значения, которые имеет каждое устройство (например, UDID).Другой вариант - позволить пользователю выбрать контакт из адресной книги, который представляет себя, и использовать эти данные.

0 голосов
/ 19 мая 2013
NSString *dname=[[UIDevice currentDevice] name];
dname=[dname componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"'的"]][0];
...