Too many arguments to function call, expected 0, have 3 - xcode

This compiles/works fine with Xcode 5, but causes a compile error with Xcode 6 Beta 4:
objc_msgSend(anItem.callback_object,
NSSelectorFromString(anItem.selector), dict);
This is a 3rd-party component, so while I have the source code, it's not really my code and I'm hesitant to change it much (despite my personal opinion of 'wtf why are they using objc_msgSend??').
Image with possibly useful detail (error in error browser):

If you think having to do this is annoying and pointless you can disable the check in the build settings by setting 'Enable strict checking of objc_msgSend Calls' to no

Just to spare watching a WWDC video, the answer is you need to strong type objc_msgSend for the compiler to build it:
typedef void (*send_type)(void*, SEL, void*);
send_type func = (send_type)objc_msgSend;
func(anItem.callback_object, NSSelectorFromString(anItem.selector), dict);
Here is another sample when calling instance methods directly, like this:
IMP methodInstance = [SomeClass instanceMethodForSelector:someSelector];
methodInstance(self, someSelector, someArgument);
Use strong type for methodInstance to make LLVM compiler happy:
typedef void (*send_type)(void*, SEL, void*);
send_type methodInstance = (send_type)[SomeClass instanceMethodForSelector:someSelector];
methodInstance(self, someSelector, someArgument);
Do not forget to set send_type's return and argument types according to your specific needs.

I found the answer, and it's in Session 417 from 2014 WWDC "What's New in LLVM". If you find this code in a 3rd party library, such as Apsalar, updating to the latest version fixes it (probably because it's not distributed as a lib, ha). For an example of casting of these calls, see THObserversAndBinders library - I'm using it and noticed that the author updated the code, such as here:
https://github.com/th-in-gs/THObserversAndBinders/blob/master/THObserversAndBinders/THObserver.m

This could also be caused by running pod install using Cocoapods 0.36.beta.2. I have reported the issue to CocoaPods. "Workaround" by using CocoaPods 0.35

Setting Enable strict checking of objc_msgSend Calls to NO, solved my issue. Below is the screenshot

Maciej Swic is right.This is caused in Pods after updating Cocoapods to 0.36.beta.2.
I found a simple workaround by type casting objc_msgSend:
id (*typed_msgSend)(id, SEL) = (void *)objc_msgSend;
id<MyProtocol> obJ = typed_msgSend(controller, #selector(myselector));

I was getting this error with QuickDialog. Following on to james_alvarez's answer but for AppCode, go to Project Settings, then click on QuickDialog under Project/Shared Settings, scroll down to ENABLE_STRICT_OBJC_MSGSEND and enter NO for Debug and Release.

You can also disable this with a post install hook:
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['ENABLE_STRICT_OBJC_MSGSEND'] = 'NO'
end
end
end

#include <objc/message.h>
void foo(void *object) {
typedef void (*send_type)(void *, SEL, int);
send_type func = (send_type)objc_msgSend;
func(object, sel_getUid("foo:"), 5);
}

Following the accepted answer- to find the answer in the given codebase might be cumbersome for few, so here's the quick snap that should solve this problem.
I edited the code in ActionSheetPicker in my project, which was causing me the same problem, like this -
- (void)notifyTarget:(id)target didSucceedWithAction:(SEL)action origin:(id)origin {
if ([target respondsToSelector:action]) {
((id (*)(id, SEL, NSDate *, id))objc_msgSend)(target, action, self.selectedDate, origin);
return;
} else if (nil != self.onActionSheetDone) {
self.onActionSheetDone(self, self.selectedDate, origin);
return;
}
NSAssert(NO, #"Invalid target/action ( %s / %s ) combination used for ActionSheetPicker", object_getClassName(target), (char *)action);
}
So look at the change that objc_msgSend portion has, compared to your current code.
The idea is to include the type of the parameters you are passing to objc_msgSend

((void(*)(id,SEL,id))objc_msgSend)(target, sel, newValue);
Change the code like above, after Xcode 12, simply setting Setting Enable strict checking of objc_msgSend Calls to NO does not help. modify the (id,SEL,id) for your need, for example(id,SEL) for two arguments, etc

This block of code reproduces the error:
- (void)reportSuccess:(void(^)(void))success
{
success(what_is_this);
}
Guess where error is? Of course, what_is_this is not declared, but somehow magically it shows another error. In other words looks like if you have block, you can put any parameters when calling it, even non existent variables.

Related

Xcode UI Testing: Automatically taking snapshot when predicates fail?

Xcode UI Testing takes automatic screenshots for viewing in the results navigator whenever a test fails, which is greatly helpful. However, that does not include tests that fail because a predicate is failed. Since predicates are often for basic checks (such as if an element exists or not on a current view), that is a huge drawback because a screenshot would be useful in diagnosing what was happening in the app when the test failed.
Does anyone know how to force a screenshot? Does this require integrating the Fastlane Snapshot tool?
On tearDown you can check if test failed (that's helpful if you are not discarding screenshots when tests pass.)
if let failureCount = testRun?.failureCount, failureCount > 0 {
takeScreenshot()
}
If you are using Xcode 9 already, the takeScreenshot function can use the new API (If not, then use the workaround mentioned by the other answer) :
let screenshot = XCUIScreen.main.screenshot()
let attach = XCTAttachment(screenshot: screenshot)
add(attach)
You can also name the attach and change its lifetime ;)
See Apple's documentation for how to use and where to find them (the "Report navigator" in View > Navigators > Reports) in more detail.
You don't have to integrate Fastlane Snapshot for this. The only trick Snapshot is doing to force screenshot is triggering this code:
XCUIDevice.shared().orientation = .unknown
This will not alter UI as described on Snapshot documentation.
Unfortunately this will not work if you're using expectation for your predicate and you put this code into waitForExpectations(timeout:handler:) handler closure and I don't know why.
To workaround this you can create your own XCTestObservation handler like this:
class MockObserver: NSObject, XCTestObservation {
func testCase(_ testCase: XCTestCase, didFailWithDescription description: String, inFile filePath: String?, atLine lineNumber: UInt) {
XCUIDevice.shared().orientation = .unknown
}
}
XCTestObservationCenter.shared().addTestObserver(MockObserver())
You can put this code in either setUp() method or specific test... method.
The test output is a little weird as it will show "Set device orientation to Unknown" as an error and actual predicate error inside but you will have your screenshot:
You can override the recordFailure method to capture screenshots on any kinds of failures.
override func recordFailure(withDescription description: String, inFile filePath: String, atLine lineNumber: Int, expected: Bool) {
add(XCTAttachment(screenshot: XCUIScreen.main.screenshot()))
super.recordFailure(withDescription: description, inFile: filePath, atLine: lineNumber, expected: expected)
}

Swift 2, warning: could not load any Objective-C class information from the dyld shared cache

I have found a few questions regarding this issue, yet none of them were helping with my problem. I am trying to save an object to core data using this code (which worked perfectly fine in Xcode 6 and Simulator...):
let fetchRequest = NSFetchRequest(entityName: "Patient")
let fetchedResults : [NSManagedObject]!
do {
fetchedResults = try managedContext.executeFetchRequest(fetchRequest) as! [NSManagedObject]
patienten = fetchedResults
} catch {
print("error")
}
I added the do-try-catch once I started working on this project in the Xcode 7 beta and a physical device.
Now, when I hit the Save button, this piece of code is called, the app freezes and I get the following:
warning: could not load any Objective-C class information from the dyld shared cache. This will significantly reduce the quality of type information available.
Does anybody know where I went wrong?
For anyone coming across this in the future, I just ran into this problem myself and it turned out that I was actually getting a stack overflow from a recursive function.
Apparently calling setValue:forKey: on an NSObject calls the respective set[Key] function, where [Key] is the (capitalized) name you gave to the forKey section.
So, if like me, you have code that looks like the following, it will cause an infinite loop and crash.
func setName(name: String) {
self.setValue(name, forKey: "name")
}
Choose Product > Clean
I had similar issue. I deleted the app from the device. Then "Product->Clean" in the XCode menu. When I ran the app again, the issue got resolved.
Swift 3:
Actually this problem happened often when you have any property in input declared as type NSError and the compiler expect an Error output, so change the input type to Error usually solve this issue.
What helped me in similar problem (xCode 7, Swift 2):
reading this question
Or more quickly without explaining the reason of solution: just comment #objc(className) in your NSManagedObjectSubclass , that was generated from your CoreData Entity (#objc(Patient) - in your case ).
This solution (if issue still appears) does not applicable to xCode 7.1/Swift 2.1, as the way of generating NSManagedObjectSubclasses was changed.
Don't forget about cleaning your project (Product > Clean) and deleting the app from your device/simulator to replace CoreData storage on it.
let fetchRequest = NSFetchRequest(entityName: "Patient")
do {
let fetchedResults = try managedObjectContext!.executeFetchRequest(fetchRequest)
print("\(fetchedResults)")
} catch {
print("error")
}
The above code worked for me.
Maybe the issue maybe with how your core data is managed.
Check if your managedObjectContext is actually getting created.
Check the modelling of your core data

determining location of deprecation warning on Ember.js

I upgraded to Ember 1.18 and I'm getting:
DEPRECATION: Using currentWhen with {{link-to}} is deprecated in favor of `current-when`.
at Ember.LinkView.EmberComponent.extend.init (http://example.com:8000/static/assets/vendor.js:33811:15)
at apply (http://example.com:8000/static/assets/vendor.js:32885:32)
at superWrapper [as init] (http://example.com:8000/static/assets/vendor.js:32459:15)
at apply (http://example.com:8000/static/assets/vendor.js:32885:32)
at new Class (http://example.com:8000/static/assets/vendor.js:47485:9)
at Function.Mixin.create.create (http://example.com:8000/static/assets/vendor.js:47943:16)
at CoreView.extend.createChildView (http://example.com:8000/static/assets/vendor.js:56278:23)
at Object.merge.appendChild (http://example.com:8000/static/assets/vendor.js:54369:26)
at CoreView.extend.appendChild (http://example.com:8000/static/assets/vendor.js:56161:34)
None of the traceback is my code, and I'm mainly using {link-to-animated} (without currentWhen explicitly).
How can I figure out where to find the problematic code?
The deprecation notice isn't showing a traceback to your code because the issue isn't in your code. :) Take a look at ember-animated-outlet.js and you'll see that currentWhen is used internally.
There's a few dirty tricks to silence deprecation warnings, but I would suggest just submitting a pull-request to the repo to have it changed. It should be a fairly easy fix.
EDIT: It seems there's already a pull request for that, but it hasn't been merged yet. So about those dirty tricks... If you're bugged by the deprecation warning, you can always override Ember.deprecate. Put the following somewhere before your app code is run (maybe in a vendor script):
var oldDeprecate = Ember.deprecate;
Ember.deprecate = function(message) {
if (message.indexOf('currentWhen') >= 0) {
return;
}
return oldDeprecate.apply(this, arguments);
};

How to use NSMaxXEdge in Cocoa app with Swift (Xcode 6)?

I've tried to create a Cocoa app which uses NSPopover internally. One of the popover's method is showRelativeToRect: ofView: preferredEdge:, which triggers an popover in Cocoa app.
If you use Objective-C in Xcode 5.1, you can execute the method with the method above, like this:
[popover showRelativeToRect: sender.bounds ofView: sender preferredEdge: NSMaxXEdge];
However, when I tried to use the method in Swift in Xcode 6, the message Use of unresolved identifier 'NSMaxXEdge' was shown when I wrote the following method, which is just a rewrite of the Objective-C method above:
popover.showRelativeToRect(sender.bounds, ofView: sender, preferredEdge: NSMaxXEdge
So where is the NSMaxXEdge gone? The official documentation says it is of type NSRectEdge, but what is the NSRectEdge? The doc doesn't link to NSRectEdge page.
Also, Xcode 5 documentation also says it is NSRectEdge, but again, no link exists there. So how can I know about what it is all about?
And finally, if NSMaxXEdge is no longer available in Xcode 6, what is the alternative?
In Foundation/NSGeometary.h of 10.10 SDK:
typedef enum {
NSMinXEdge = 0,
NSMinYEdge = 1,
NSMaxXEdge = 2,
NSMaxYEdge = 3
} NSRectEdge;
So it should be NSRectEdge.from(2) or NSRectEdge(2) or just pass 2 will be fine.
If you try this:
println("NSRectEdge.max: \(NSRectEdge.max)") // 9223372036854775807
println("NSRectEdge.from(2): \(NSRectEdge.from(2))") // 2
println("NSRectEdge(2): \(NSRectEdge(2))") //2
You will know that .max was actually the max positive signed Int for 64-bit.
(Tho, I can't be sure since it's not really mentioned in documentation anywhere.)
NSRectEdge has a static var called max. I think you should just use that. For example:
popover.showRelativeToRect(rect, ofView: view, preferredEdge: NSRectEdge.max)
(The below is true for beta 5 (developing for 10.9). Your mileage may vary.)
Above, you get a solution that works - passing 0-3 where the function calls for a NSRectEdge. I'd like to pick up on
how can I know about what it is all about?
The documentation indicates that NSRectEdge is bridged with CGRectEdge, but trying to pass in CGRectEdge led to an error of
CGRectEdge is not convertible to NSRectEdge
NSRectEdge.from(2) or NSRectEdge(2) - as suggested above - come back with the error that
NSRectEdge has no accessible initializers
When you type NSRectEdge into Xcode, however, it shows two types:
CGRectEdge (which in this case is useless, see above) and Int.
I'm afraid that you need to guess that NSRectEdge is an enum when you see it both called as a string and defined as an int; but from there to looking up its definition in the framework is a logical step; as is guessing that you will have four values, one for each edge.
Incidentally, there seems to be an internal modulo operation going on somewhere - when you pass it '4', you get NSMinXEdge again and so on.

Address Book is returning old values

I am having a problem with the AddressBook framework.
It all seems to be stemming from ABCopyRecordForUniqueId returning a record with old data.
Example:
I run up the program below in one terminal window - it shows the current data.
I make a change through the address book UI - my program continues to show old data.
I run up another instance of the same program in a new terminal window - it shows the updated data.
I have tried posting on the omnigroup site with no luck :( so any guidance is really appreciated
PS: If you would like to try the code, to get an address book ID you can export a contact as a vCard and open it with a text editor
int main (int argc, const char * argv[])
{
ABAddressBookRef addressBook = ABGetSharedAddressBook();
while(1)
{
ABRecordRef addressBookRecord = NULL;
addressBookRecord = ABCopyRecordForUniqueId(addressBook, CFSTR("4064D587-0378-4DCF-A6B9-D3702F01C94C:ABPerson"));
CFShow(addressBookRecord);
CFRelease(addressBookRecord);
sleep(1);
}
return 0;
}
I tried your example myself and am seeing the same problem. Out of curiosity, I tried asking for the shared address book inside the loop (in case there was some weirdness going on with the address book singleton) but this made no difference. I checked out the documentation (ABAddressBook C Reference) as well as the higher-level address book framework reference and guide. As far as I can tell, you're doing the right thing.
I'd file this as a bug against the framework.
thanks for the suggestion. I did file a report but it turns out this is expected
Annoying that it wasn't in the docs..
"Engineering has determined that this issue behaves as intended based on the following information:
The address book requires the run loop to be run in order to receive updates from other applications. Instead of sleep(1), use CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1.0, false)."
Thanks,
M

Resources