Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Instantiating an NSMutableAttributedString while importing SwiftyAttributes causes build error on Xcode 10 #29

Closed
ketzusaka opened this issue Jun 25, 2018 · 7 comments

Comments

@ketzusaka
Copy link
Contributor

We've had this issue in our project preventing Xcode 10 compilation since the release. The error is:

Foundation.NSMutableAttributedString:11:12: note: found this candidate
    public init(string str: String, attributes attrs: [NSAttributedStringKey : Any]? = nil)
           ^
Foundation.NSAttributedString:19:12: note: found this candidate
    public init(string str: String, attributes attrs: [NSAttributedStringKey : Any]? = nil)

The usage was pretty basic, something like so:

let string = NSMutableAttributedString(string: "Hello World", attributes: [.strokeColor: UIColor.green])

After digging into it I discovered this doesn't happen unless we're importing SwiftyAttributes. If you duplicate the testInit_withStringAndAttributes test method, but replace the NSAttributedStrings with NSMutableAttributedStrings you'll get the same error when running the tests.

Attempting to use the convenience initializer on a NSMutableAttributedString results in the following error:

Cannot convert value of type '[Attribute]' to expected argument type '[NSAttributedStringKey : Any]?'

Taking out the convenience initializer on NSAttributedString, or giving the attributes parameter a different name resolves the issue.

It's likely that this is a bug with Swift. I'm not sure if you'd rather file a bug with them and see what happens, or resolve the issue within the library now. Changing the attributes parameter would be a breaking change and be cause for a major bump.

Let me know if you're going to take action on this at the library level if ya can, as it is preventing us from building on XC10 :)

Here's the diff w/ the fix and test that I experimented with:

diff --git a/SwiftyAttributes/Sources/common/NSAttributedString+SwiftyAttributes.swift b/SwiftyAttributes/Sources/common/NSAttributedString+SwiftyAttributes.swift
index 76a0b01..6c3a934 100644
--- a/SwiftyAttributes/Sources/common/NSAttributedString+SwiftyAttributes.swift
+++ b/SwiftyAttributes/Sources/common/NSAttributedString+SwiftyAttributes.swift
@@ -30,8 +30,8 @@ extension NSAttributedString {
      - parameter    str:            The string for the new attributed string.
      - parameter    attributes:     The attributes for the new attributed string.
      */
-    public convenience init(string str: String, attributes: [Attribute]) {
-        self.init(string: str, attributes: dictionary(from: attributes))
+    public convenience init(string str: String, swiftyAttributes attrs: [Attribute]) {
+        self.init(string: str, attributes: dictionary(from: attrs))
     }
 
     /**
diff --git a/SwiftyAttributesTests/NSAttributedString_Tests.swift b/SwiftyAttributesTests/NSAttributedString_Tests.swift
index 60947b3..79845e4 100644
--- a/SwiftyAttributesTests/NSAttributedString_Tests.swift
+++ b/SwiftyAttributesTests/NSAttributedString_Tests.swift
@@ -12,7 +12,7 @@ import SwiftyAttributes
 class NSAttributedString_Tests: XCTestCase {
     
     func testInit_withStringAndAttributes() {
-        let subject = NSAttributedString(string: "Hello World", attributes: [.strokeColor(.green), .strokeWidth(3)])
+        let subject = NSAttributedString(string: "Hello World", swiftyAttributes: [.strokeColor(.green), .strokeWidth(3)])
         #if swift(>=4.0)
             let expected = NSAttributedString(string: "Hello World", attributes: [.strokeColor: Color.green, .strokeWidth: 3])
         #else
diff --git a/SwiftyAttributesTests/NSMutableAttributedString_Tests.swift b/SwiftyAttributesTests/NSMutableAttributedString_Tests.swift
index 5577b2e..f95aba3 100644
--- a/SwiftyAttributesTests/NSMutableAttributedString_Tests.swift
+++ b/SwiftyAttributesTests/NSMutableAttributedString_Tests.swift
@@ -10,6 +10,16 @@ import XCTest
 import SwiftyAttributes
 
 class NSMutableAttributedString_Tests: XCTestCase {
+
+    func testInitMutable_withStringAndAttributes() {
+        let subject = NSMutableAttributedString(string: "Hello World", swiftyAttributes: [.strokeColor(.green), .strokeWidth(3)])
+        #if swift(>=4.0)
+        let expected = NSMutableAttributedString(string: "Hello World", attributes: [.strokeColor: Color.green, .strokeWidth: 3])
+        #else
+        let expected = NSMutableAttributedString(string: "Hello World", attributes: [NSStrokeColorAttributeName: Color.green, NSStrokeWidthAttributeName: 3])
+        #endif
+        XCTAssertEqual(subject, expected)
+    }
     
     func testAddAttributes_usingSwiftRange() {
         let subject = "Hello".withTextColor(.orange)
@ketzusaka ketzusaka changed the title Instantiating an NSMutableAttributedString while importing SwiftyAttributes causes build error on Xcode 10 Instantiating an NSMutableAttributedString while importing SwiftyAttributes causes build error on Xcode 10 Jun 25, 2018
@eddiekaiger
Copy link
Owner

eddiekaiger commented Jun 25, 2018

Thanks for pointing this out @ketzusaka. That's pretty strange that it only happens on NSMutableAttributedString 🤔. I may file a bug with Swift, but it would probably be good to change the parameter labels either way so it doesn't confuse the compiler. I'm down for the swiftyAttributes name change. Do you want to make the PR? Otherwise I can take care of it :)

@ketzusaka
Copy link
Contributor Author

Yeah, I’ll open one once I get to the office :)

Thanks!

ketzusaka added a commit to ketzusaka/SwiftyAttributes that referenced this issue Jun 25, 2018
…0's Swift compiler

When instantiating an `NSMutableAttributedString` in a target that imports SwiftyAttributes on Xcode 10 the compiler was getting confused on which initializer to use. The convenience initializer added to `NSAttributedString` seems to be throwing the compiler out of whack. This updates argument names to give a clearer distinction and resolves the issue.

See issue eddiekaiger#29 for more details.
@eddiekaiger
Copy link
Owner

Fixed and released in v5.0.0 :)

@wigl
Copy link

wigl commented Oct 15, 2018

I did the test in my FrameWork.

When I just add convenience init func in extension NSAttributedString, Xcode 10 compilation no error, The code is:

extension NSAttributedString {
    
    public convenience init(string str: String, attributes: [String]) {
        self.init(string: str, attributes: nil)
    }
}

But, when also add new func and parameter type is NSAttributedString.EnumerationOptions, Xcode 10 compilation error, The code is:

extension NSAttributedString {
    
    public convenience init(string str: String, attributes: [String]) {
        self.init(string: str, attributes: nil)
    }
    
    func test(options: NSAttributedString.EnumerationOptions) {
        
    }
}

I delete the options: NSAttributedString.EnumerationOptions, or use string Int or other type instead of NSAttributedString.EnumerationOptions, Xcode 10 compilation success.

@eddiekaiger
Copy link
Owner

@wigl I don't think this pertains to the issue above -- but what's the compilation error you're getting? I can't reproduce it on Xcode 10.

@wigl
Copy link

wigl commented Oct 18, 2018

I forgot to tell you that the above code is inside the framework.
127
129

@wigl
Copy link

wigl commented Oct 18, 2018

When the above extension is in the main project, there is no problem. @eddiekaiger

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants