Seguimos con el especial de Swift 3 (del que podéis leer la primera parte aquí y en esta ocasión vamos a centrarnos en uno de los cambios más importantes y que acaba de ser aprobado en su versión final. Nos referimos al cambio de evolución SE-0086 que corresponde a «Eliminar el prefijo NS en la Fundación de Swift».
Este es uno de los principales cambios por los que nuestro código no funcionará en Swift 3, pero al ser una equivalencia de 1 a 1 mediante tablas aprobadas, la adaptación de estos cambios mediante el asistente de migración (en la mayoría de los casos) será rápida e «indolora».
Reglas del cambio
La eliminación o no del prefijo vendrá derivada de una serie de condiciones pre-establecidas para conseguir una coherencia en el cambio en sí.
- Si la clase es específica de Objective-C, o heredada desde su runtime y el espacio de nombres
NS
, se mantendrá el prefijoNS
. Caso de objetos como:NSObject
,NSAutoReleasePool
,NSException
oNSProxy
. - Si la clase es específica de la plataforma, se mantendrá el prefijo
NS
. Aunque algunos ahora pertenecen a la Fundación del lenguaje, su espacio de nombres es de un framework de mayor nivel comoUIKit
oAppKit
. Por lo tanto, todas aquellas que pertenezcan a APIs de mayor nivel conservarán el prefijo, comoNSUserNotificacion
oNSBackgroundActivity
. - Si la clase tiene un equivalente como tipo por valor, conservará el prefijo, como
NSArray
oNSString
. - Si la clase tendrá en un futuro próximo un equivalente de tipo por valor, conservará igualmente el prefijo, como
NSAttributedString
oNSPredicate
. - La clases y protocolos
NSLock
tendrá una importancia especial en los esfuerzos generales de concurrencia en futuras versiones del lenguaje, por lo que mantendrán el prefijo. - Hay algunos tipos de colección implementados en la Fundación que normalmente son genéricos sobre objetos y no sobre el tipo
Any
. Arreglar esto requerirá que varios tipos se conviertan en structs, por lo que los tipos específicos equivalentes de Objective-C se convertirían en específicos del lenguaje y obligarán a que no se quite el prefijoNS
en un futuro próximo. Así que algunos comoNSCache
,NSMapTable
oNSOrderedSet
conservarán su nombre de cara al futuro cambio en Swift. - Algunos tipos perderán el prefijo pero también cambiarán de nombre, para darles uno más claro y descriptivo, como el caso de
NSTask
que pasará a llamarseProcess
.
Tabla de cambios de nombre
Siguiendo estas reglas, los siguientes tipos en Objective-C perderán el prefijo NS
pasando a tener un nombre sin él.
Nombre en Objective-C | Nombre en Swift | Notas |
---|---|---|
NSBlockOperation | BlockOperation | |
NSBundle | Bundle | |
NSByteCountFormatter | ByteCountFormatter | |
NSCachedURLResponse | CachedURLResponse | |
NSComparisonResult | ComparisonResult | |
NSDateComponentsFormatter | DateComponentsFormatter | |
NSDateFormatter | DateFormatter | |
NSDateIntervalFormatter | DateIntervalFormatter | |
NSDistributedNotificationCenter | DistributedNotificationCenter | |
NSEnergyFormatter | EnergyFormatter | |
NSFileHandle | FileHandle | |
NSFileManager | FileManager | |
NSFileManagerDelegate | FileManagerDelegate | |
NSFileWrapper | FileWrapper | |
NSFormatter | Formatter | |
NSHost | Host | |
NSHTTPCookie | HTTPCookie | |
NSHTTPCookieStorage | HTTPCookieStorage | |
NSHTTPURLResponse | HTTPURLResponse | |
NSInputStream | InputStream | |
NSJSONSerialization | JSONSerialization | |
NSLengthFormatter | LengthFormatter | |
NSMassFormatter | MassFormatter | |
NSMessagePort | MessagePort | |
NSNetService | NetService | |
NSNetServiceBrowser | NetServiceBrowser | |
NSNetServiceBrowserDelegate | NetServiceBrowserDelegate | |
NSNetServiceDelegate | NetServiceDelegate | |
NSNotificationCenter | NotificationCenter | |
NSNotificationName | NotificationName | |
NSNotificationQueue | NotificationQueue | |
NSNumberFormatter | NumberFormatter | |
NSOperatingSystemVersion | OperatingSystemVersion | |
NSOperation | Operation | |
NSOperationQueue | OperationQueue | |
NSOutputStream | OutputStream | La librería estándar de Swift tiene un tipo OutputStream que será renombrado a OutputStreamable . |
NSPersonNameComponentsFormatter | PersonNameComponentsFormatter | |
NSPipe | Pipe | |
NSPort | Port | |
NSPortDelegate | PortDelegate | |
NSPortMessage | PortMessage | |
NSProcessInfo | ProcessInfo | |
NSProgress | Progress | |
NSProgressReporting | ProgressReporting | |
NSPropertyListSerialization | PropertyListSerialization | |
NSQualityOfService | QualityOfService | |
NSRunLoop | RunLoop | |
NSScanner | Scanner | |
NSSocketPort | SocketPort | |
NSStream | Stream | |
NSStreamDelegate | StreamDelegate | |
NSTask | Process | La librería estándar tiene un tipo Process . Su funcionalidad será incorporada al tipo ProcessInfo haciendo que el actual enum desaparezca. |
NSThread | Thread | |
NSTimeInterval | TimeInterval | |
NSTimer | Timer | |
NSUndoManager | UndoManager | |
NSURLAuthenticationChallenge | URLAuthenticationChallenge | |
NSURLAuthenticationChallengeSender | URLAuthenticationChallengeSender | |
NSURLCache | URLCache | |
NSURLCredential | URLCredential | |
NSURLCredentialStorage | URLCredentialStorage | |
NSURLProtectionSpace | URLProtectionSpace | |
NSURLProtocol | URLProtocol | |
NSURLProtocolClient | URLProtocolClient | |
NSURLRequest | URLRequest | |
NSURLResponse | URLResponse | |
NSURLSession | URLSession | |
NSURLSessionConfiguration | URLSessionConfiguration | |
NSURLSessionDataDelegate | URLSessionDataDelegate | |
NSURLSessionDataTask | URLSessionDataTask | |
NSURLSessionDelegate | URLSessionDelegate | |
NSURLSessionDownloadDelegate | URLSessionDownloadDelegate | |
NSURLSessionDownloadTask | URLSessionDownloadTask | |
NSURLSessionStreamDelegate | URLSessionStreamDelegate | |
NSURLSessionStreamTask | URLSessionStreamTask | |
NSURLSessionTask | URLSessionTask | |
NSURLSessionTaskDelegate | URLSessionTaskDelegate | |
NSURLSessionUploadTask | URLSessionUploadTask | |
NSUserDefaults | UserDefaults | |
NSXMLDocument | XMLDocument | |
NSXMLDTD | XMLDTD | |
NSXMLDTDNode | XMLDTDNode | |
NSXMLElement | XMLElement | |
NSXMLNode | XMLNode | |
NSXMLParser | XMLParser | |
NSXMLParserDelegate | XMLParserDelegate |
Tipos embebidos
Los siguientes tipos serán elevados a la clase contenedora como subtipo, formando parte de la misma.
Antiguo nombre | Nuevo nombre |
---|---|
NSActivityOptions | ProcessInfo.ActivityOptions |
NSAppleEventSendOptions | NSAppleEventDescriptor.SendOptions |
NSAttributedStringEnumerationOptions | AttributedString.EnumerationOptions |
NSBackgroundActivityResult | NSBackgroundActivityScheduler.Result |
NSByteCountFormatterCountStyle | ByteCountFormatter.CountStyle |
NSByteCountFormatterUnits | ByteCountFormatter.Units |
NSCalculationError | Decimal.CalculationError |
NSCalendarOptions | Calendar.Options |
NSCalendarUnit | Calendar.Unit |
NSComparisonPredicateModifier | ComparisonPredicate.Modifier |
NSComparisonPredicateOptions | ComparisonPredicate.Options |
NSCompoundPredicateType | CompoundPredicate.LogicalType |
NSDataBase64DecodingOptions | NSData.Base64DecodingOptions |
NSDataBase64EncodingOptions | NSData.Base64EncodingOptions |
NSDataReadingOptions | NSData.ReadingOptions |
NSDataSearchOptions | NSData.SearchOptions |
NSDataWritingOptions | NSData.WritingOptions |
NSDateFormatterBehavior | DateFormatter.Behavior |
NSDateFormatterStyle | DateFormatter.Style |
NSDateIntervalFormatterStyle | DateIntervalFormatter.Style |
NSDecodingFailurePolicy | Coder.DecodingFailurePolicy |
NSDirectoryEnumerationOptions | FileManager.DirectoryEnumerationOptions |
NSDistributedNotificationOptions | DistributedNotificationCenter.Options |
NSEnergyFormatterUnit | EnergyFormatter.Unit |
NSExpressionType | NSExpression.ExpressionType |
NSFileCoordinatorReadingOptions | FileCoordinator.ReadingOptions |
NSFileCoordinatorWritingOptions | FileCoordinator.WritingOptions |
NSFileManagerItemReplacementOptions | FileManager.ItemReplacementOptions |
NSFileManagerUnmountOptions | FileManager.UnmountOptions |
NSFileVersionAddingOptions | FileVersion.AddingOptions |
NSFileVersionReplacingOptions | FileVersion.ReplacingOptions |
NSFileWrapperReadingOptions | FileWrapper.ReadingOptions |
NSFileWrapperWritingOptions | FileWrapper.WritingOptions |
NSFormattingContext | Formatter.Context |
NSFormattingUnitStyle | Formatter.UnitStyle |
NSHTTPCookieAcceptPolicy | HTTPCookie.AcceptPolicy |
NSInsertionPosition | NSPositionalSpecifier.InsertionPosition |
NSItemProviderErrorCode | NSItemProvider.ErrorCode |
NSJSONReadingOptions | JSONSerialization.ReadingOptions |
NSJSONWritingOptions | JSONSerialization.WritingOptions |
NSLengthFormatterUnit | LengthFormatter.Unit |
NSLinguisticTaggerOptions | NSLinguisticTagger.Options |
NSLocaleLanguageDirection | Locale.LanguageDirection |
NSMachPortOptions | NSMachPort.Options |
NSMassFormatterUnit | MassFormatter.Unit |
NSMatchingFlags | RegularExpression.MatchingFlags |
NSMatchingOptions | RegularExpression.MatchingOptions |
NSMeasurementFormatterUnitOptions | MeasurementFormatter.UnitOptions |
NSNetServiceOptions | NetService.Options |
NSNetServicesError | NetService.ErrorCode |
NSNotificationCoalescing | NotificationQueue.NotificationCoalescing |
NSNotificationSuspensionBehavior | DistributedNotificationCenter.SuspensionBehavior |
NSNumberFormatterBehavior | NumberFormatter.Behavior |
NSNumberFormatterPadPosition | NumberFormatter.PadPosition |
NSNumberFormatterRoundingMode | NumberFormatter.RoundingMode |
NSNumberFormatterStyle | NumberFormatter.Style |
NSOperationQueuePriority | Operation.QueuePriority |
NSPersonNameComponentsFormatterOptions | PersonNameComponentsFormatter.Options |
NSPersonNameComponentsFormatterStyle | PersonNameComponentsFormatter.Style |
NSPointerFunctionsOptions | PointerFunctions.Options |
NSPostingStyle | NotificationQueue.PostingStyle |
NSPredicateOperatorType | ComparisonPredicate.Operator |
NSProcessInfoThermalState | ProcessInfo.ThermalState |
NSPropertyListFormat | PropertyListSerialization.PropertyListFormat |
NSPropertyListMutabilityOptions | PropertyListSerialization.MutabilityOptions |
NSPropertyListReadOptions | PropertyListSerialization.ReadOptions |
NSPropertyListWriteOptions | PropertyListSerialization.WriteOptions |
NSRegularExpressionOptions | RegularExpression.Options |
NSRelativePosition | NSRelativeSpecifier.RelativePosition |
NSSearchPathDirectory | FileManager.SearchPathDirectory |
NSSearchPathDomainMask | FileManager.SearchPathDomainMask |
NSSocketNativeHandle | Socket.NativeHandle |
NSStreamEvent | Stream.Event |
NSStreamStatus | Stream.Status |
NSStringCompareOptions | NSString.CompareOptions |
NSStringEncoding | NSString.Encoding |
NSStringEncodingConversionOptions | NSString.EncodingConversionOptions |
NSStringEnumerationOptions | NSString.EnumerationOptions |
NSTaskTerminationReason | Task.TerminationReason |
NSTestComparisonOperation | NSSpecifierTest.TestComparisonOperation |
NSTextCheckingType | TextCheckingResult.CheckingType |
NSTimeZoneNameStyle | TimeZone.NameStyle |
NSURLCacheStoragePolicy | URLCache.StoragePolicy |
NSURLCredentialPersistence | URLCredential.Persistence |
NSURLRelationship | FileManager.URLRelationship |
NSURLRequestCachePolicy | URLRequest.CachePolicy |
NSURLRequestNetworkServiceType | URLRequest.NetworkServiceType |
NSURLSessionAuthChallengeDisposition | URLSession.AuthChallengeDisposition |
NSURLSessionResponseDisposition | URLSession.ResponseDisposition |
NSURLSessionTaskState | URLSessionTask.State |
NSURLSessionTaskMetricsResourceFetchType | URLSessionTaskMetrics.ResourceFetchType |
NSUserNotificationActivationType | NSUserNotification.ActivationType |
NSVolumeEnumerationOptions | FileManager.VolumeEnumerationOptions |
NSWhoseSubelementIdentifier | NSWhoseSpecifier.SubelementIdentifier |
NSXMLDocumentContentKind | XMLDocument.ContentKind |
NSXMLDTDNodeKind | XMLDTDNode.Kind |
NSXMLNodeKind | XMLNode.Kind |
NSXMLParserError | XMLParser.ErrorCode |
NSXMLParserExternalEntityResolvingPolicy | XMLParser.ExternalEntityResolvingPolicy |
NSXPCConnectionOptions | NSXPCConnection.Options |
Enumeraciones actualizadas
Los miembros de la enumeración NSExpressionType
pierden su sufijo y quedan de la siguiente forma:
extension Expression { public enum ExpressionType : UInt { case constantValue case evaluatedObject case variable case keyPath case function case unionSet case intersectSet case minusSet case subquery case aggregate case anyKey case block @available(OSX 10.11, iOS 9.0, *) case conditional }
Las enumeraciones asociadas a ComparisonPredicate
igualmente pierden el sufijo, quedando así:
extension ComparisonPredicate { public struct Options : OptionSet { public init(rawValue: UInt) public static var caseInsensitive: ComparisonPredicate.Options { get } public static var diacriticInsensitive: ComparisonPredicate.Options { get } public static var normalized: ComparisonPredicate.Options { get } } public enum Modifier : UInt { case direct case all case any } public enum Operator : UInt { case lessThan case lessThanOrEqualTo case greaterThan case greaterThanOrEqualTo case equalTo case notEqualTo case matches case like case beginsWith case endsWith case `in` case customSelector case contains case between } }
Los tipos NSDateFormatterStyle
y NSDateIntervalFormatterStyle
también pierden el sufijo y la opción no
pasa a ser none
.
extension DateIntervalFormatter { @available(OSX 10.10, iOS 8.0, *) public enum Style : UInt { case none case short case medium case long case full } }
Igualmente NSNumberFormatterStyle
también perderá el sufijo y no
pasa a ser none
para mayor coherencia.
extension NumberFormatter { public enum Style : UInt { case none case decimal case currency case percent case scientific case spellOut @available(OSX 10.11, iOS 9.0, *) case ordinal @available(OSX 10.11, iOS 9.0, *) case currencyISOCode @available(OSX 10.11, iOS 9.0, *) case currencyPlural @available(OSX 10.11, iOS 9.0, *) case currencyAccounting } }
Los tipos enumerados NSXMLDocumentContentKind
, NSXMLDTDNodeKind
y NSXMLNodeKind
cambian de nombre a los siguientes según las definiciones, por orden.
extension XMLDocument { public enum ContentKind : UInt { case xml case xhtml case html case text } } extension XMLDTDNode { public enum Kind : UInt { case generalEntity case parsedEntity case unparsedEntity case parameterEntity case predefinedEntity case cdataAttribute case idAttribute case idRefAttribute case idRefsAttribute case entityAttribute case entitiesAttribute case nmTokenAttribute case nmTokensAttribute case enumerationAttribute case notationAttribute case undefinedElementDeclaration case emptyElementDeclaration case anyElementDeclaration case mixedElementDeclaration case elementDeclarationElement } } extension XMLNode { public enum Kind : UInt { case invalid case document case element case attribute case namespace case processingInstruction case comment case text case dtd case entityDeclaration case attributeDeclaration case elementDeclaration case notationDeclaration } }
Todas las enumeraciones que no están en esta sección conservarán el prefijo NS
. En futuras versiones del lenguaje serán evaluados caso por caso para contemplar si han de ser renombrados o no.
NSStringEncoding
Por último, el tipo NSStringEncoding
tiene una serie de constantes que serán renombradas como miembros de la estructura de tipo RawRepresentable
llamada String.Encoding
.
extension String { public struct Encoding : RawRepresentable { public var rawValue: UInt public init(rawValue: UInt) public static var ascii { get } public static var nextstep { get } public static var japaneseEUC { get } public static var utf8 { get } public static var isoLatin1 { get } public static var symbol { get } public static var nonLossyASCII { get } public static var shiftJIS { get } public static var isoLatin2 { get } public static var unicode { get } public static var windowsCP1251 { get } public static var windowsCP1252 { get } public static var windowsCP1253 { get } public static var windowsCP1254 { get } public static var windowsCP1250 { get } public static var iso2022JP { get } public static var macOSRoman { get } public static var utf16 { get } public static var utf16BigEndian { get } public static var utf16LittleEndian { get } public static var utf32 { get } public static var utf32BigEndian { get } public static var utf32LittleEndian { get } } }
Conclusiones
Como vemos, los cambios no son pocos ni muchos menos. Pero son fáciles de intuir y la mayoría convertibles fácilmente con ayuda del asistente de migración.
En mi experiencia con Swift 3, no he tenido ni un solo problema pues la ayuda del lenguaje te proporciona la nueva clase en cuanto empiezas a escribir la antigua, y si no, el propio compilador te lanza una advertencia. Así que el proceso de adaptación será fácil.
Nos vemos la próxima semana con la siguiente entrega y Good Apple Coding.