更好的方式从设备获取用户的名字?

我做了一个从设备名称中提取用户名的function。

这个想法是跳过设置步骤,让用户第一次启动应用程序, 直接玩

这是一个次优的方法 ,因为我永远不能相信设备名称来保存用户的名字。 问题是:有什么更好的方法来做到这一点?

我的function在下面得到正确的名字…

  • …如果设备的默认名称没有改变(“Sanna的iPod”)
  • … 用英语,
  • …用法语和类似语言(“iPod de Sanna”)
  • …如果名字不以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; } 

我用它在我的应用程序中build议用户名。 这样,大多数用户不必费心编写他们的用户名。

我的应用程序没有连接到任何其他服务,如iTunes或Facebook,但每个用户都需要一个用户名。 那么我怎么得到这个名字?

我想对Ricky Helegesson的回答进行改进。 它具有以下特点;

  • 虽然效率较低,但因为使用了正则expression式,所以稍微小一些,但是我认为应该只调用一次。
  • 我已经花费了“手机”以及“iPod”,“iPhone”和“iPad”。
  • 它只是在“iPad”,“iPhone”之前,只在string的末尾删除“”。
  • 如“iPad模拟器”中那样,它们是第一个字,就是“iPad”等等。
  • 它大写每个单词的第一个字母。
  • 这是不区分大小写的。
  • 这是一个函数,因为它没有依赖关系。

这里是代码:

 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. 正则expression式分为三部分,
    1. 在string的开始处,匹配但不返回“iPhone”,“iPod”,“iPad”或“电话”和可选词“de”。
    2. 在string的末尾,匹配并返回一个单词,后面跟随可选的“s”(不返回),然后返回“iPad”,“iPhone”,“iPod”或“电话”(不返回其一)。
    3. 这个匹配和以前一样,但是它应该适用于中文设备名称。 (改编自Travis蠕虫的提交,请告诉我是否错误)
    4. 匹配并返回任何与先前规则不匹配的单词。
  2. 遍历所有的匹配,大写他们并将其添加到数组。
  3. 返回数组。

如果一个名字以“s”结尾,在“iPad”之前没有撇号,我不会试图去改变它,因为如果“s”是名字的一部分或者是名字。

请享用!

这是一个替代scheme,即获得所有的名字。 而且,它不会在使用“de”或“s”的语言结尾处删除“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]; 

我已经将原始的Owen Godfrey答案转换为斯威夫特,并更新了正则expression式,以支持更多的模式,如User's iPhone 6SiPhone 5 de User

我在这里创build了一个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 } } 

如果这只是为了iPod和iPhone,那么为什么还要使用用户名呢? 如果您需要为您的Web服务识别设备,则每个设备都有其他唯一值(例如UDID)。 其他选项是让用户从地址簿中select一个代表自己并使用该数据的联系人。

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