Skip to content

Commit

Permalink
Merge pull request #32 from eddiekaiger/swift-5
Browse files Browse the repository at this point in the history
Swift 5 and Xcode 10.2 Support
  • Loading branch information
eddiekaiger authored Apr 4, 2019
2 parents 18df307 + 44624a6 commit 32331ff
Show file tree
Hide file tree
Showing 22 changed files with 169 additions and 914 deletions.
4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
language: objective-c
osx_image: xcode9
osx_image: xcode10.2

env:
- PLATFORM=iOS CODECOV=ios DESTINATION='platform=iOS Simulator,name=iPhone 6S'
- PLATFORM=Mac CODECOV=osx DESTINATION='platform=OS X'
- PLATFORM=tvOS CODECOV=tvos DESTINATION='platform=tvOS Simulator,name=Apple TV 1080p'
- PLATFORM=tvOS CODECOV=tvos DESTINATION='platform=tvOS Simulator,name=Apple TV'

script:
- xcodebuild -version
Expand Down
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

#### *A Swifty API for attributed strings.*

![Swift Version](https://img.shields.io/badge/swift-4-orange.svg?style=flat)
![Swift Version](https://img.shields.io/badge/swift-3.2-orange.svg?style=flat)
![Swift Version](https://img.shields.io/badge/swift-5-orange.svg?style=flat)
![Swift Version](https://img.shields.io/badge/swift-4.2-orange.svg?style=flat)
[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)
[![CocoaPods Compatible](https://img.shields.io/cocoapods/v/SwiftyAttributes.svg)](https://img.shields.io/cocoapods/v/SwiftyAttributes.svg)
[![Platform](https://img.shields.io/cocoapods/p/SwiftyAttributes.svg?style=flat)](http://cocoapods.org/pods/SwiftyAttributes)
Expand Down Expand Up @@ -39,8 +39,8 @@ let fancyString = "Hello".withFont(.systemFont(ofSize: 12)) + " World!".withFont
# Requirements

* iOS 8.0+, macOS 10.11+, watchOS 2.0+, tvOS 9.0+
* Swift 4 or 3
* Xcode 9 or 10
* Swift 4.2+
* Xcode 10.0+

# Installation

Expand Down Expand Up @@ -71,7 +71,7 @@ Initializing attributed strings in `SwiftyAttributes` can be done several ways:
NSAttributedString(string: "Hello World", swiftyAttributes: [.kern(5), .backgroundColor(.gray)])
````

You can retrieve the attribute at a specific location using an attribute name from the `Attribute.Name` enum:
You can retrieve the attribute at a specific location using the built-in `NSAttributedString.Key` enum:
````swift
let attr: Attribute? = myAttributedString.swiftyAttribute(.shadow, at: 5)
````
Expand Down
2 changes: 1 addition & 1 deletion SwiftyAttributes.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Pod::Spec.new do |s|

s.name = "SwiftyAttributes"
s.version = "5.0.0"
s.version = "5.1.0"
s.summary = "A Swifty API for attributed strings."

s.description = <<-DESC
Expand Down
22 changes: 8 additions & 14 deletions SwiftyAttributes.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
C03659091DC85AE40051F06D /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C03658EF1DC84B3F0051F06D /* Images.xcassets */; };
C05082291DFA72F700D39B3B /* Attribute+Sequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = C050821E1DFA72F700D39B3B /* Attribute+Sequence.swift */; };
C050822A1DFA72F700D39B3B /* Attribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = C050821F1DFA72F700D39B3B /* Attribute.swift */; };
C050822B1DFA72F700D39B3B /* AttributeName.swift in Sources */ = {isa = PBXBuildFile; fileRef = C05082201DFA72F700D39B3B /* AttributeName.swift */; };
C050822C1DFA72F700D39B3B /* Ligatures.swift in Sources */ = {isa = PBXBuildFile; fileRef = C05082211DFA72F700D39B3B /* Ligatures.swift */; };
C050822D1DFA72F700D39B3B /* NSAttributedString+SwiftyAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = C05082221DFA72F700D39B3B /* NSAttributedString+SwiftyAttributes.swift */; };
C050822E1DFA72F700D39B3B /* NSMutableAttributedString+SwiftyAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = C05082231DFA72F700D39B3B /* NSMutableAttributedString+SwiftyAttributes.swift */; };
Expand All @@ -33,7 +32,6 @@
C09633E01DD806F600059332 /* SwiftyAttributes.h in Headers */ = {isa = PBXBuildFile; fileRef = C09633DC1DD8056000059332 /* SwiftyAttributes.h */; settings = {ATTRIBUTES = (Public, ); }; };
C0DB42EC1DDED3500093A6FA /* NSAttributedString+macOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0DB42EB1DDED3500093A6FA /* NSAttributedString+macOS.swift */; };
C0E1C9541DD319D50068E85C /* SwiftyAttributes.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C0E1C94B1DD319D50068E85C /* SwiftyAttributes.framework */; };
C0E1C96A1DD31A0D0068E85C /* Attribute_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0D753FC1DC5C88900BB9754 /* Attribute_Tests.swift */; };
C0E1C96B1DD31A0D0068E85C /* NSMutableAttributedString_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C08D04121DC39B5500575F98 /* NSMutableAttributedString_Tests.swift */; };
C0E1C96C1DD31A0D0068E85C /* NSAttributedString_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C08D04141DC3B16A00575F98 /* NSAttributedString_Tests.swift */; };
C0E1C96D1DD31A0D0068E85C /* SwiftyAttributes_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0E211581D9EC5C000623F02 /* SwiftyAttributes_Tests.swift */; };
Expand Down Expand Up @@ -85,7 +83,6 @@
C03659051DC859D80051F06D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
C050821E1DFA72F700D39B3B /* Attribute+Sequence.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "Attribute+Sequence.swift"; path = "common/Attribute+Sequence.swift"; sourceTree = "<group>"; };
C050821F1DFA72F700D39B3B /* Attribute.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Attribute.swift; path = common/Attribute.swift; sourceTree = "<group>"; };
C05082201DFA72F700D39B3B /* AttributeName.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = AttributeName.swift; path = common/AttributeName.swift; sourceTree = "<group>"; };
C05082211DFA72F700D39B3B /* Ligatures.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Ligatures.swift; path = common/Ligatures.swift; sourceTree = "<group>"; };
C05082221DFA72F700D39B3B /* NSAttributedString+SwiftyAttributes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "NSAttributedString+SwiftyAttributes.swift"; path = "common/NSAttributedString+SwiftyAttributes.swift"; sourceTree = "<group>"; };
C05082231DFA72F700D39B3B /* NSMutableAttributedString+SwiftyAttributes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "NSMutableAttributedString+SwiftyAttributes.swift"; path = "common/NSMutableAttributedString+SwiftyAttributes.swift"; sourceTree = "<group>"; };
Expand All @@ -106,7 +103,6 @@
C09633DC1DD8056000059332 /* SwiftyAttributes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SwiftyAttributes.h; sourceTree = "<group>"; };
C09633DE1DD8057A00059332 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
C0D753FA1DC5C77E00BB9754 /* TextEffect_Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextEffect_Tests.swift; sourceTree = "<group>"; };
C0D753FC1DC5C88900BB9754 /* Attribute_Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Attribute_Tests.swift; sourceTree = "<group>"; };
C0DB42EB1DDED3500093A6FA /* NSAttributedString+macOS.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSAttributedString+macOS.swift"; sourceTree = "<group>"; };
C0E1C94B1DD319D50068E85C /* SwiftyAttributes.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SwiftyAttributes.framework; sourceTree = BUILT_PRODUCTS_DIR; };
C0E1C9531DD319D50068E85C /* SwiftyAttributesTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SwiftyAttributesTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
Expand Down Expand Up @@ -208,7 +204,6 @@
C0E211571D9EC5C000623F02 /* SwiftyAttributesTests */ = {
isa = PBXGroup;
children = (
C0D753FC1DC5C88900BB9754 /* Attribute_Tests.swift */,
C027C0CA1DEA452500953C09 /* Attribute+Sequence_Tests.swift */,
C08D04121DC39B5500575F98 /* NSMutableAttributedString_Tests.swift */,
C08D04141DC3B16A00575F98 /* NSAttributedString_Tests.swift */,
Expand All @@ -228,7 +223,6 @@
children = (
C050821F1DFA72F700D39B3B /* Attribute.swift */,
C050821E1DFA72F700D39B3B /* Attribute+Sequence.swift */,
C05082201DFA72F700D39B3B /* AttributeName.swift */,
C05082211DFA72F700D39B3B /* Ligatures.swift */,
C05082221DFA72F700D39B3B /* NSAttributedString+SwiftyAttributes.swift */,
C05082231DFA72F700D39B3B /* NSMutableAttributedString+SwiftyAttributes.swift */,
Expand Down Expand Up @@ -355,7 +349,7 @@
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0810;
LastUpgradeCheck = 0930;
LastUpgradeCheck = 1020;
ORGANIZATIONNAME = "Eddie Kaiger";
TargetAttributes = {
C03658F61DC859D80051F06D = {
Expand All @@ -369,20 +363,20 @@
};
C0E1C94A1DD319D50068E85C = {
CreatedOnToolsVersion = 8.1;
LastSwiftMigration = 0810;
LastSwiftMigration = 1020;
ProvisioningStyle = Manual;
};
C0E1C9521DD319D50068E85C = {
CreatedOnToolsVersion = 8.1;
DevelopmentTeam = 5KT4ZVPMF8;
LastSwiftMigration = 0810;
LastSwiftMigration = 1020;
ProvisioningStyle = Automatic;
};
};
};
buildConfigurationList = C0E211441D9EC5C000623F02 /* Build configuration list for PBXProject "SwiftyAttributes" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Expand Down Expand Up @@ -465,7 +459,6 @@
C050822A1DFA72F700D39B3B /* Attribute.swift in Sources */,
C050822F1DFA72F700D39B3B /* Operators.swift in Sources */,
C050822E1DFA72F700D39B3B /* NSMutableAttributedString+SwiftyAttributes.swift in Sources */,
C050822B1DFA72F700D39B3B /* AttributeName.swift in Sources */,
C05082331DFA72F700D39B3B /* WritingDirection.swift in Sources */,
C050822C1DFA72F700D39B3B /* Ligatures.swift in Sources */,
C05082311DFA72F700D39B3B /* TextEffect.swift in Sources */,
Expand All @@ -486,7 +479,6 @@
C0E1C96E1DD31A0D0068E85C /* WritingDirection_Tests.swift in Sources */,
C0E1C96B1DD31A0D0068E85C /* NSMutableAttributedString_Tests.swift in Sources */,
C0E1C96D1DD31A0D0068E85C /* SwiftyAttributes_Tests.swift in Sources */,
C0E1C96A1DD31A0D0068E85C /* Attribute_Tests.swift in Sources */,
C0E1C9701DD31A0D0068E85C /* TextEffect_Tests.swift in Sources */,
C027C0C91DEA0A0100953C09 /* SpellingState_Tests.swift in Sources */,
C0F96A031DEDE1D300D039A4 /* VerticalGlyphForm_Tests.swift in Sources */,
Expand Down Expand Up @@ -682,6 +674,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
Expand Down Expand Up @@ -735,7 +728,7 @@
SUPPORTED_PLATFORMS = "watchsimulator watchos appletvos appletvsimulator iphoneos iphonesimulator macosx";
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 4.0;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2,3,4";
TVOS_DEPLOYMENT_TARGET = 9.0;
VERSIONING_SYSTEM = "apple-generic";
Expand All @@ -748,6 +741,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
Expand Down Expand Up @@ -793,7 +787,7 @@
PRODUCT_BUNDLE_PACKAGE_TYPE = BNDL;
SUPPORTED_PLATFORMS = "watchsimulator watchos appletvos appletvsimulator iphoneos iphonesimulator macosx";
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_VERSION = 4.0;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2,3,4";
TVOS_DEPLOYMENT_TARGET = 9.0;
VALIDATE_PRODUCT = YES;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0930"
LastUpgradeVersion = "1020"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0930"
LastUpgradeVersion = "1020"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0930"
LastUpgradeVersion = "1020"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0930"
LastUpgradeVersion = "1020"
version = "1.7">
<BuildAction
parallelizeBuildables = "YES"
Expand Down
34 changes: 7 additions & 27 deletions SwiftyAttributes/Sources/common/Attribute+Sequence.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,41 +9,21 @@
/**
An extension on dictionaries that allows us to convert a Foundation-based dictionary of attributes to an array of `Attribute`s.
*/
#if swift(>=4.0)
extension Dictionary where Key == AttributeName {

/// Returns an array of `Attribute`s converted from the dictionary of attributes. Use this whenever you want to convert [NSAttributeStringKey: Any] to [Attribute].
public var swiftyAttributes: [Attribute] {
return map(Attribute.init)
}
extension Dictionary where Key == NSAttributedString.Key {

/// Returns an array of `Attribute`s converted from the dictionary of attributes. Use this whenever you want to convert [NSAttributeStringKey: Any] to [Attribute].
public var swiftyAttributes: [Attribute] {
return map(Attribute.init)
}
#else
/**
A Sequence with an iterator of (String, Any) is equivalent to [String: Any]
This is a simple syntactic workaround since we can't write "extension Dictionary where Key == String". Thanks Swift :)
*/
extension Sequence where Iterator.Element == (key: String, value: Any) {

/// Returns an array of `Attribute`s converted from the dictionary of attributes. Use this whenever you want to convert [String: Any] to [Attribute].
public var swiftyAttributes: [Attribute] {
return flatMap { name, value in
if let attrName = AttributeName(rawValue: name) {
return Attribute(name: attrName, foundationValue: value)
} else {
return nil
}
}
}

}
#endif
}

extension Sequence where Iterator.Element == Attribute {

/// Returns the attribute dictionary required by Foundation's API for attributed strings. Use this whenever you need to convert [Attribute] to [String: Any].
public var foundationAttributes: [StringKey: Any] {
return reduce([StringKey: Any]()) { dictionary, attribute in
public var foundationAttributes: [NSAttributedString.Key: Any] {
return reduce([NSAttributedString.Key: Any]()) { dictionary, attribute in
var dict = dictionary
dict[attribute.keyName] = attribute.foundationValue
return dict
Expand Down
49 changes: 10 additions & 39 deletions SwiftyAttributes/Sources/common/Attribute.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,8 @@ public typealias ParagraphStyle = NSParagraphStyle

#if os(watchOS)
#else
public typealias Shadow = NSShadow
public typealias TextAttachment = NSTextAttachment
#endif

#if swift(>=4.2)
public typealias AttributeName = NSAttributedString.Key
#elseif swift(>=4.0)
public typealias AttributeName = NSAttributedStringKey
#else
public typealias AttributeName = Attribute.Name
public typealias Shadow = NSShadow
public typealias TextAttachment = NSTextAttachment
#endif

/**
Expand Down Expand Up @@ -141,7 +133,7 @@ public enum Attribute {
/// A custom attribute with a given attribute name and value.
case custom(String, Any)

init(name: AttributeName, foundationValue: Any) {
init(name: NSAttributedString.Key, foundationValue: Any) {
func validate<Type>(_ val: Any) -> Type {
assert(val is Type, "Attribute with name \(name.rawValue) must have a value of type \(Type.self)")
return val as! Type
Expand Down Expand Up @@ -190,31 +182,15 @@ public enum Attribute {
case .strokeColor: ret = .strokeColor(validate(foundationValue))
case .strokeWidth: ret = .strokeWidth(validateDouble(foundationValue))
case .strikethroughColor: ret = .strikethroughColor(validate(foundationValue))
case .strikethroughStyle:
#if swift(>=4.2)
let style = StrikethroughStyle(rawValue: validate(foundationValue))
#else
let style = StrikethroughStyle(rawValue: validate(foundationValue))!
#endif
ret = .strikethroughStyle(style)
case .strikethroughStyle: ret = .strikethroughStyle(StrikethroughStyle(rawValue: validate(foundationValue)))
case .foregroundColor: ret = .textColor(validate(foundationValue))
case .textEffect: ret = .textEffect(TextEffect(rawValue: validate(foundationValue))!)
case .underlineColor: ret = .underlineColor(validate(foundationValue))
case .underlineStyle:
#if swift(>=4.2)
let style = UnderlineStyle(rawValue: validate(foundationValue))
#else
let style = UnderlineStyle(rawValue: validate(foundationValue))!
#endif
ret = .underlineStyle(style)
case .underlineStyle: ret = .underlineStyle(UnderlineStyle(rawValue: validate(foundationValue)))
case .verticalGlyphForm: ret = .verticalGlyphForm(VerticalGlyphForm(rawValue: validate(foundationValue))!)
case .writingDirection:
let values: [Int] = validate(foundationValue)
#if swift(>=4.1)
ret = .writingDirections(values.compactMap(WritingDirection.init))
#else
ret = .writingDirections(values.flatMap(WritingDirection.init))
#endif
ret = .writingDirections(values.compactMap(WritingDirection.init))
default:
if ret == nil {
ret = .custom(name.rawValue, foundationValue)
Expand All @@ -225,9 +201,8 @@ public enum Attribute {
}

/// The key name corresponding to the attribute.
public var keyName: StringKey {

var name: AttributeName!
public var keyName: NSAttributedString.Key {
var name: NSAttributedString.Key!

// Bug in Swift prevents us from putting directives inside switch statements (https://bugs.swift.org/browse/SR-2)

Expand Down Expand Up @@ -273,15 +248,11 @@ public enum Attribute {
case .writingDirections: name = .writingDirection
case .verticalGlyphForm: name = .verticalGlyphForm
case .custom(let attributeName, _) where name == nil:
name = AttributeName(rawValue: attributeName)
name = NSAttributedString.Key(rawValue: attributeName)
default: break
}

#if swift(>=4.0)
return name
#else
return name.rawValue
#endif
return name
}

// Convenience getter variable for the associated value of the attribute. See each case to determine the return type.
Expand Down
Loading

0 comments on commit 32331ff

Please sign in to comment.