Asked  7 Months ago    Answers:  5   Viewed   52 times

I submitted my app a little over a week ago and got the dreaded rejection email today. It tells me that my app cannot be accepted because I'm using a non-public API; specifically, it says,

The non-public API that is included in your application is firstResponder.

Now, the offending API call is actually a solution I found here on SO:

UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow];
UIView   *firstResponder = [keyWindow performSelector:@selector(firstResponder)];

How do I get the current first responder on the screen? I'm looking for a way that won't get my app rejected.

 Answers

60

In one of my applications I often want the first responder to resign if the user taps on the background. For this purpose I wrote a category on UIView, which I call on the UIWindow.

The following is based on that and should return the first responder.

@implementation UIView (FindFirstResponder)
- (id)findFirstResponder
{
    if (self.isFirstResponder) {
        return self;        
    }
    for (UIView *subView in self.subviews) {
        id responder = [subView findFirstResponder];
        if (responder) return responder;
    }
    return nil;
}
@end

iOS 7+

- (id)findFirstResponder
{
    if (self.isFirstResponder) {
        return self;
    }
    for (UIView *subView in self.view.subviews) {
        if ([subView isFirstResponder]) {
            return subView;
        }
    }
    return nil;
}

Swift:

extension UIView {
    var firstResponder: UIView? {
        guard !isFirstResponder else { return self }

        for subview in subviews {
            if let firstResponder = subview.firstResponder {
                return firstResponder
            }
        }

        return nil
    }
}

Usage example in Swift:

if let firstResponder = view.window?.firstResponder {
    // do something with `firstResponder`
}
Tuesday, June 1, 2021
 
samayo
answered 7 Months ago
32

I had a similar problem when I did major changes to my Podfile. My solution was to remove the workspace file and run pod install again:

rm -rf MyProject.xcworkspace
pod install
Wednesday, June 9, 2021
 
oroshnivskyy
answered 7 Months ago
29

Right overall picture, wrong implementation details in the first paragraph.

A "First Responder" in a NibFile is an Object …

No, actually, First Responder is nil. Connecting a UI control (e.g., button) to First Responder in a nib is equivalent to [control setTarget:nil] in code.

The reason for the First Responder fake-object in the nib window is that, in IB, you set target and action at the same time (ctrl-drag to target, choose action from pop-up menu). You can't set the action and leave the target unset, like you can in code, so to set it to nil, you need to do so explicitly. That's what First Responder is for: it's a fake object representing nil, so you can set the target and action the same way you would do when setting it to a specific real target.

Of course, you can't use this to set anything else to nil, only views' targets. You can only use it to mean First Responder, not anything else.

So if the user klicks on an UI control, the Nib sets …

The nib doesn't do anything. It's just a freeze-dried collection of objects stored on disk. Even when you instantiate NSNib, all you're doing is defrosting some objects. It's the objects that do things.

In the case at hand, when you unarchive the control you connected to First Responder from the nib, its target is set to nil (remember, that's what First Responder really is: a target of nil). When a control's target is nil, and the user clicks on it, it sends its action to whichever responder is the first responder at the time.

Your second and third paragraphs are correct.

Monday, July 12, 2021
 
RahulG
answered 5 Months ago
41

If I try to get friends of a random user I get HTTP 500 but it contains this response:

{
   "error": {
      "type": "Exception",
      "message": "(#604) Can't lookup all friends of <UID>. Can only lookup for the logged in user (<MY_UID>), or friends of the logged in user with the appropriate permission"
   }
}

which is pretty self-explanatory.

If I try to get friends of my friend who allows viewing his other friends it works fine. If my friend chose to not allow viewing his other friends I get the same error.

Friday, July 30, 2021
 
Kenny
answered 5 Months ago
46

You are making this much harder than it needs to be.

In Interface Builder, set the initialFirstResponder outlet of your window to point to your text field.

That's it.

If you absolutely must do it programmatically, use:

[window setInitialFirstResponder:yourTextField];

Remember, if you're fighting with Cocoa to do something that seems like it should be simple, then you're probably doing it wrong.

Saturday, October 2, 2021
 
max_
answered 2 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :  
Share