Подтвердить что ты не робот

Лучший способ получить имя пользователя с устройства?

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

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

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

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

  • ... если имя по умолчанию для устройства не изменилось ( "Sanna iPod" )
  • ... на английском языке,
  • ... по-французски и аналогичным ( "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, но для каждого пользователя требуется имя пользователя. Итак, как мне получить имя?

4b9b3361

Ответ 1

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

  • Он немного меньше, хотя и менее эффективен, потому что он использует регулярные выражения, но потом я предполагаю, что он должен вызываться только один раз.
  • Я потратил его на включение "телефона", а также "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:@" "];

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

  • Регулярное выражение содержит три части;
    • В начале строки нужно совместить, но не возвращать "iPhone", "iPod" , "iPad" или "phone" и необязательное слово "de".
    • В конце строки сопоставьте и верните слово, за которым следуют и необязательные "'s" (который не возвращается), а затем "iPad" , "iPhone", "iPod" или "phone" (который также не возвращаются).
    • Этот матч совпадает с предыдущим, но он должен работать для китайских имен устройств. (Адаптировано из сообщения Travis Worm. Скажите, пожалуйста, если это неправильно.)
    • Соответствует и возвращает любое слово, которое не соответствует предыдущим правилам.
  • Итерации по всем совпадениям, их использование и их добавление в массив.
  • Возвращает массив.

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

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

Ответ 2

Вот альтернатива, которая получает все имена. Кроме того, он не удаляет '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

Я преобразовал исходный ответ Owen Godfrey в Swift и обновил Regexpr для поддержки большего количества шаблонов, таких как User 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
}
}

Ответ 4

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

Ответ 5

NSString *dname=[[UIDevice currentDevice] name];
dname=[dname componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"'的"]][0];