Array extension called from other module - swift

Array extension methods are unavailable from other modules (for example the XCTest project)
For the sake of simplicity the code below does nothing but it can be used to reproduce the error
import Foundation
extension Array {
mutating func myMethod(toIndex: Int) -> Int! {
// no real code, it's here only to show the problem
return 0
}
}
Calling it from the same module works as expected but from a test class don't
class MyProjectTests: XCTestCase {
func testMoveObjectsFromIndexes1() {
var arr = ["000", "001", "002", "003"]
arr.myMethod(0)
}
}
I think this is correct because the method visibility is restricted to its own module, indeed I obtain the error '[String]' does not have a member named 'myMethod'
I've tried to define the extended method as public as shown below
extension Array {
public mutating func myMethod(toIndex: Int) -> Int! {
// no real code, it's here only to show the problem
return 0
}
}
But I get the compile error 'Extension of generic type 'Array<T>' from a different module cannot provide public declarations'
Until Beta 7 using public solved the problem but under XCode 6.1 (6A1046a) I obtain this error
How can I fix it to run under other modules/projects?

Swift does not allow public extensions currently so you will need to include that extension swift file in your project and put it part of the target.

While not entirely solving the original question, I did find that I could test extension methods in Swift 2.0 (Under XCode 7.0) by importing the module with the #testable directive:
#testable import MyGreatModule

Related

A Swift Tour, compiler error around public property in Protocol and Extensions section

I'm new to Swift and am going through the playground for the official A Swift Tour tutorial. I'm executing the code as-is, but am getting a compiler error when running the following block:
extension Int: ExampleProtocol {
var simpleDescription: String {
return "The number \(self)"
}
mutating func adjust() {
self += 42
}
}
print(7.simpleDescription)
The protocol is defined as follows:
protocol ExampleProtocol {
var simpleDescription: String { get }
mutating func adjust()
}
The compiler error is:
error: Protocols and Extensions.xcplaygroundpage:41:9: error: property 'simpleDescription' must be declared public because it matches a requirement in public protocol 'ExampleProtocol'
var simpleDescription: String {
^
Protocols and Extensions.xcplaygroundpage:41:9: note: mark the property as 'public' to satisfy the requirement
var simpleDescription: String {
^
public
I've tried adding public in front of simpleDescription but then I get an unexpected pattern error.
Anyone know what's going on here?
Turns out although my Xcode version was correctly 12.1, my local Swift version was 5.2.4 (the tutorial assumes 5.3). I installed the Command Line Tools for Xcode 12 package, which updated my Swift to 5.3 and now the code compiled as expected. I used xcrun swift -version to see which version of Swift Xcode was using.

'Method' is ambiguous for type lookup in this context, Error in Alamofire

I am using Alamofire for network handling in swift and run into one weird error. It seems like we can't pass Method enum as parameter. [Error is on Method parameter]
private func apiRequest(method: Method, url: String, apiData: [String : AnyObject], completion:(finished: Bool, response: AnyObject?) ->Void) {
Alamofire.request(method, url, parameters: apiData).responseJSON{ response in
if let JSON = response.result.value {
completion(finished: true, response: JSON)
} else {
completion(finished: false, response:nil)
}
}
}
You have to specify the module from which to lookup object type.
Call Alamofire.Method
There is probably a name collision. To solve it, you can use the qualified name of the enum (including the module name):
private func apiRequest(method: Alamofire.Method, ...
I have also encountered this problem, because I have declared a number of the same name of the protocol:
protocol SomeProtocol {
static func someTypeMethod()
}
protocol SomeProtocol {
init(someParameter: Int)
}
protocol SomeProtocol {
var mustBeSettable: Int { get set }
var doesNotNeedToBeSettable: Int { get }
}
Had this error conflict when using "Moya" and when bridging a c framework, fixed it by implicitly adding Moya.Method module.
var method: Moya.Method {
switch self {
case .login: return .post
case .register: return .post
}
}
The type Method is declared in two imported modules. You have to specify the module from which to use the type. Use Alamofire.Method instead of Method.
Tip: If you are using the type often, you can create a type alias in your module (application):
typealias Method = Alamofire.Method
That way you will not need to prefix the type with Alamofire. any more.
While the answer to this did fix the build error; in my case, the file showing the warning was in two different frameworks so Xcode did not know where to look. This was not the intended behavior of our internal frameworks so I simply removed the copy I no longer wanted.
You may have a class declared in two or more places in your application. The error is saying that there is no conclusive way to use this class because there are a couple different places in the code it is declared.
Swift 4 and Alamofire 4.7
Replace HTTPMethod to Alamofire.HTTPMethod
I got this error because my database table name and model class name was same...Issue resolved by renaming model class name.
Change the enum type name to different &...
Use the $(inherited) flag, or
Remove the build settings from the target.
Target - > building settings- >ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES, Value type is Boolean, click on the other, change the value to $(inherited)
perform - pod update
Done
then try to run Your project , error will gone ! (I have tried in my project)
enum 'XYZ'ButtonType {
}
I managed to fix the problem by deleting the Alamofire folder in the pods project manually. Then, I do a "pod install" to reinstall the missing pods.
There are significantly less files in the Alamofire folder after doing this.

'unresolved identifier' for return value of Type Method in Swift

I'm trying to access the return value from a Type Method in one file from another file. To wit:
file_1:
class LetterView: UIView {
class func testFunction() -> CGSize {
return CGSizeMake(100,200)
}
}
file_2:
class AnotherClass {
func callTestFunction() {
var result = LetterView.testFunction()
print("- breakpoint here - ")
}
}
I get an Unresolved Identifier error on var result if I put a breakpoint in the debugger and do a po result. However if I change the return type of testFunction() to be an Int (say 2) and return that instead, then the function call works as expected. Color me confused.
Is the second file importing UIKit as well? Also, you should update your example from function to func. This all works in the playground which leads to UIKit missing.
There could be a few possible issues.
One of the classes has a Testing target and other one doesn't. You have to even include all of your classes in the testing target or none of them.
If it's Objective C class, check that the class is in ObjectiveC bridging header file.
If it's NSManagedObject subclass. Add #objc(className) before the class declaration.
If it's part of a different framework, make sure that the class or function is public
This is the original answer link : Swift Compiler Error: Use of unresolved identifier 'name'

Swift Generics and Protocol Extensions

I have a protocol Reusablethat has a static function static func reuseId() -> String and a protocol extension that defines the default implementation for the function. Then, I implemented a extension on UITableViewCell to conform to the Reusable protocol. I can now use the function on my TableViewCells without a problem: SomeTableViewCell.reuseId().
The Problem I have is with Generics. I have a generic class that has a generic parameter of the type UITableViewCell:
internal class SomeClass<CellType: UITableViewCell>: NSObject {
...
}
I want to be able to use the function specified in Reusable in my generic class on CellType but unfortunately this does not work as expected. The compiler always generates the error Type 'CellType' has no member 'reuseId'.
Does anybody know why this is happening? Is there a workaround?
I am using Xcode 7.0 with Swift 2.0.
Greetings from Germany
UPDATE: Here is some sample code that better shows my problem:
import UIKit
protocol Reusable {
static func reuseId() -> String
}
extension Reusable {
static func reuseId() -> String {
return String(self).componentsSeparatedByString(".").last!
}
}
extension UITableViewCell: Reusable { }
class SomeGenericClass<CellType: UITableViewCell> {
func someFunction() {
let reuseIdentifier = CellType.reuseId()
}
}
This Code will generate the above error but I do not quite understand why this happens. I think the main difference to the sample code that jtbandes posted is that I use a static function.
UPDATE: The issue is fixed in Xcode 8.3 beta 2. The sample code above now works as expected (after migrating it to Swift 3 of course).
That's an interesting problem. Your code seems like it should work; you might want to file an enhancement request.
Here's a workaround that seems to work correctly:
class SomeGenericClass<CellType: Cell> {
func someFunction() {
let reuseIdentifier = (CellType.self as Reusable.Type).reuseId()
}
}
Another (workaround) way to get what you need:
class GenericExample<CellType:UITableViewCell where CellType:Reusable>
{
func test() -> String {
return CellType.reuseId()
}
}
GenericExample<UITableViewCell>().test() // returns "UITableViewCell"
GenericExample<MyCell>().test() // returns "MyCell"

Calling a global function which has the same name as a member function Part 2

Directly related to Calling a global function which has the same name as a member function, I'm wondering how to call a global function in my own module.
I have a project named Parsing that is a Cocoa Framework. The name of my Xcode target is Parsing.
I have a function named failure at the framework level, and I'm attempting to call it from within a member of a type that has the same name.
I can obviously work around this by changing names; but I'm more curious about why the qualified name isn't working for me.
I get the compile error Use of unresolved identifier 'Parsing' in the following code:
import Foundation
//import Parsing;
func failure<T>() -> ParserOf<T> {
return ParserOf { inp in nil }
}
class ParserOf<T> {
let _parser:String -> (T, String)?;
private init(_ p:String -> (T, String)?) {
_parser = p;
}
func parse(s:String) -> (T, String)? {
return _parser(s);
}
class func failure() -> ParserOf<T> {
return Parsing.failure(); // compile error
}
}
If I uncomment the import Parsing line then I get a compiler error that says Cannot load underlying module for 'parsing' which looks a little odd because the casing of the name in the error message doesn't match the casing of the actual name.
I usually do that by importing the framework like you did in your commented code:
import Parsing
and then using the full name, including the namespace (module), again like you did:
Parsing.failure()
You should check that:
the entity you are trying to access to (in this case a function) is declared as public
the module name (Parsing) is correct
the function is actually a global function and not a class/struct method
target -> Build Settings -> Packaging -> Product Module Name is the actual model name you are trying to import
Last, if you change the name of the class func failure() method, does it work?