简体   繁体   中英

Sinch iOS - 'NSInvalidArgumentException', '-[UIDevice reb_platform]: unrecognized selector

I'm trying to implement Sinch with the iOS SDK and despite following the documentation and tutorials carefully I keep getting this error:

2015-08-01 12:29:22.804 neighborfix[55154:2577760] mainUser username - [e-mail username redacted]

2015-08-01 12:29:22.815 neighborfix[55154:2577760] -[UIDevice reb_platform]: unrecognized selector sent to instance 0x7fc113f1ed40

2015-08-01 12:29:22.827 neighborfix[55154:2577760] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIDevice reb_platform]: unrecognized selector sent to instance 0x7fc113f1ed40'

*** First throw call stack:
(

0   CoreFoundation                      0x000000010a5cac65 __exceptionPreprocess + 165


1   libobjc.A.dylib                     0x000000010a263bb7 objc_exception_throw + 45

2   CoreFoundation                      0x000000010a5d20ad -[NSObject(NSObject) doesNotRecognizeSelector:] + 205

3   CoreFoundation                      0x000000010a52813c ___forwarding___ + 988

4   CoreFoundation                      0x000000010a527cd8 _CF_forwarding_prep_0 + 120

5   neighborfix                         0x000000010824fa69 SINUILocalNotificationWithSinchNotification + 13102

6   neighborfix                         0x0000000108234817 _ZN6rebrtc13OfflineInvite6encodeERKS0_PhmPm + 4432013

7   neighborfix                         0x000000010822f440 _ZN6rebrtc13OfflineInvite6encodeERKS0_PhmPm + 4410550

8   neighborfix                         0x0000000108241c79 SINCallOrderByStartTimeComparator + 43762

9   neighborfix                         0x00000001082418a0 SINCallOrderByStartTimeComparator + 42777

10  neighborfix                         0x0000000107d6ef24 -[AppDelegate sinchClientWithUserId:] + 116

11  neighborfix                         0x0000000107d7c31e -[MessagingViewController viewDidLoad] + 574

12  UIKit                               0x000000010abbe210 -[UIViewController loadViewIfRequired] + 738

13  UIKit                               0x000000010abbe40e -[UIViewController view] + 27

14  UIKit                               0x000000010b14b48d -[_UIFullscreenPresentationController _setPresentedViewController:] + 65

15  UIKit                               0x000000010ab98da9 -[UIPresentationController initWithPresentedViewController:presentingViewController:] + 105

16  UIKit                               0x000000010abca288 -[UIViewController _presentViewController:withAnimationController:completion:] + 1761

17  UIKit                               0x000000010abcc701 __62-[UIViewController presentViewController:animated:completion:]_block_invoke + 132

18  UIKit                               0x000000010abcc625 -[UIViewController presentViewController:animated:completion:] + 229

19  neighborfix                         0x0000000107da73e6 -[FixerRequestController submitPressed:] + 230

20  UIKit                               0x000000010aa8eda2 -[UIApplication sendAction:to:from:forEvent:] + 75

21  UIKit                               0x000000010aa8eda2 -[UIApplication sendAction:to:from:forEvent:] + 75

22  UIKit                               0x000000010aba054a -[UIControl _sendActionsForEvents:withEvent:] + 467

23  UIKit                               0x000000010ab9f919 -[UIControl touchesEnded:withEvent:] + 522

24  UIKit                               0x000000010aadb998 -[UIWindow _sendTouchesForEvent:] + 735

25  UIKit                               0x000000010aadc2c2 -[UIWindow sendEvent:] + 682

26  UIKit                               0x000000010aaa2581 -[UIApplication sendEvent:] + 246

27  UIKit                               0x000000010aaafd1c _UIApplicationHandleEventFromQueueEvent + 18265

28  UIKit                               0x000000010aa8a5dc _UIApplicationHandleEventQueue + 2066

29  CoreFoundation                      0x000000010a4fe431 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17

30  CoreFoundation                      0x000000010a4f42fd __CFRunLoopDoSources0 + 269

31  CoreFoundation                      0x000000010a4f3934 __CFRunLoopRun + 868

32  CoreFoundation                      0x000000010a4f3366 CFRunLoopRunSpecific + 470

33  GraphicsServices                    0x000000010bea4a3e GSEventRunModal + 161

34  UIKit                               0x000000010aa8d900 UIApplicationMain + 1282

35  neighborfix                         0x0000000107d7d6df main + 111

36  libdyld.dylib                       0x000000010f456145 start + 1
)

libc++abi.dylib: terminating with uncaught exception of type NSException

I've tried the following:

  1. Removed Sinch framework and re-installed latest version (3.5.2). I made sure after removing that I deleted from the file directory and all references in "Linked Frameworks and Libraries" in General and "Link Binary With Libraries" in Build Phases had no reference to Sinch before re-installing and making sure it was copied. I have all required frameworks loaded [including those for Parse conflicts] (AVFoundation, Security, Audiotoolbox, Bolts, libstc++6.0.9.dylib) and all required linker flags (-ObjC,-Xlinker,-lc++).

  2. Double-checked proper Sinch delegate implementation (SINClientDelegate,SINMessageClientDelegate) and moved entire Sinch delegate setup/implementation to AppDelegate to make it more straightforward to analyze.

  3. Tried running on actual device as well as simulator

  4. Changed Sinch app setup so that my app does not require JS authentication (even though I do not think this affects iOS SDK).

  5. Searched entire project for any reference to reb_platform and found none. This is probably a call made by a Sinch private method in its library.

Here's my relevant code:

AppDelegate.h:

#import <UIKit/UIKit.h>
#import <Sinch/Sinch.h>

@interface AppDelegate : UIResponder <UIApplicationDelegate, SINClientDelegate, SINMessageClientDelegate>

@property (strong, nonatomic) UIWindow *window;
@property (strong, nonatomic) id<SINClient> client;
@property (strong, nonatomic) id<SINMessageClient>sinchMessageClient;

- (void)sinchClientWithUserId:(NSString *)userId;
-(void)sendMessage:(NSString *)messageText toRecipient:(NSString *)recipientId;

@end

AppDelegate.m:

#import "AppDelegate.h"
#import <Parse/Parse.h>
#import <ParseUI/ParseUI.h>
#import <Fabric/Fabric.h>
#import <Crashlytics/Crashlytics.h>
#import "Config.h"




@interface AppDelegate ()

@end

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.

    [Parse enableLocalDatastore];

    // Initialize Parse
    [Parse setApplicationId:[APPID]
                  clientKey:[CLIENT-KEY]];

    // rack statistics around application opens.
    [PFAnalytics trackAppOpenedWithLaunchOptions:launchOptions];
    [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleLightContent;
    [PFImageView class];

    [[UIBarButtonItem appearanceWhenContainedIn: [UISearchBar class], nil] setTintColor:[UIColor whiteColor]];
    //[Fabric with:@[CrashlyticsKit]];


    return YES;
}



#pragma mark - Sinch
- (void)sinchClientWithUserId:(NSString *)userId
{

        self.client = [Sinch clientWithApplicationKey: [SINCHAPPKEY]
                                applicationSecret:[SINCHAPPSECRET]
                                  environmentHost:@"sandbox.sinch.com"
                                           userId:userId];
        self.client.delegate = self;

        [self.client setSupportCalling:NO];
        [self.client setSupportMessaging:YES];
        [self.client start];
        [self.client startListeningOnActiveConnection];

}

- (void)clientDidStart:(id<SINClient>)client
{
    NSLog(@"Sinch client started successfully (version: %@)", [Sinch version]);
    self.sinchMessageClient = [self.client messageClient];
    self.sinchMessageClient.delegate =  self;
}

- (void)clientDidFail:(id<SINClient>)client error:(NSError *)error
{
    NSLog(@"Sinch client error: %@", [error localizedDescription]);
}

- (void)client:(id<SINClient>)client logMessage:(NSString *)message area:(NSString *)area severity:(SINLogSeverity)severity timestamp:(NSDate *)timestamp
{
    if (severity == SINLogSeverityCritical)
    {
        NSLog(@"%@", message);
    }
}

#pragma mark SINMessageClientDelegate methods
// Receiving an incoming message.
- (void)messageClient:(id<SINMessageClient>)messageClient didReceiveIncomingMessage:(id<SINMessage>)message {
    [[NSNotificationCenter defaultCenter] postNotificationName:SINCH_MESSAGE_RECEIVED object:self userInfo:@{@"message" : message}];
}

// Finish sending a message
- (void)messageSent:(id<SINMessage>)message recipientId:(NSString *)recipientId {
    [[NSNotificationCenter defaultCenter] postNotificationName:SINCH_MESSAGE_SENT object:self userInfo:@{@"message" : message}];
}

// Failed to send a message
- (void)messageFailed:(id<SINMessage>)message info:(id<SINMessageFailureInfo>)messageFailureInfo {
    [[NSNotificationCenter defaultCenter] postNotificationName:SINCH_MESSAGE_FAILED object:self userInfo:@{@"message" : message}];
    NSLog(@"MessageBoard: message to %@ failed. Description: %@. Reason: %@.", messageFailureInfo.recipientId, messageFailureInfo.error.localizedDescription, messageFailureInfo.error.localizedFailureReason);
}

-(void)messageDelivered:(id<SINMessageDeliveryInfo>)info
{
    [[NSNotificationCenter defaultCenter] postNotificationName:SINCH_MESSAGE_SENT object:info];
}



-(void)sendMessage:(NSString *)messageText toRecipient:(NSString *)recipientId{

    SINOutgoingMessage *message = [SINOutgoingMessage messageWithRecipient:recipientId text:messageText];
    [[self.client messageClient]sendMessage:message];


}

@end

MessagingViewController.h:

#import <UIKit/UIKit.h>
#import <Parse/Parse.h>
#import <Sinch/Sinch.h>

@interface MessagingViewController : UIViewController
@property (strong, nonatomic) PFUser *selectedUser;
@end

MessagingViewController.m:

#import "MessagingViewController.h"
#import "UsersTableViewCell.h"
#import "RecipientTableViewCell.h"
#import "TextInsetLabel.h"
#import <Sinch/Sinch.h>
#import "AppDelegate.h"
#import "Config.h"


typedef NS_ENUM(int, MessageDirection)
{
    Incoming,
    Outgoing
};

@interface MessagingViewController () <UITableViewDataSource, UITableViewDelegate, UITextFieldDelegate>
@property (strong, nonatomic) NSMutableArray *messages;
@property (weak, nonatomic) IBOutlet UITableView *tableView;
@property (weak, nonatomic) IBOutlet UITextField *messageTextField;
@property (weak, nonatomic) IBOutlet UIButton *btnSendMessage;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *messagingBottomConstraint;
@end

static NSString * CELL_ID_RECIPIENT = @"RecipientCell";
static NSString * CELL_ID_USER = @"UserCell";

@implementation MessagingViewController{

    AppDelegate *delegate;
}

#pragma mark - View Lifecycle

-(void)viewWillAppear:(BOOL)animated{

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(messageDelivered:) name:SINCH_MESSAGE_RECEIVED object:nil];

}
- (void)viewDidLoad
{
    [super viewDidLoad];
    //NSLog(@"selectedUser in Messaging - %@",self.selectedUser);

    //Init our array to hold chat messages
    self.messages = [NSMutableArray new];

    //Tableview Setup
    self.tableView.rowHeight = UITableViewAutomaticDimension;
    self.tableView.estimatedRowHeight = 66.0f;

    //Textfield Setup
    [self textFieldSetup];

    //Setup Sinch message client
    PFUser *mainUser = [PFUser currentUser];
    NSLog(@"mainUser username - %@",mainUser[@"username"]);
    delegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    [delegate sinchClientWithUserId:mainUser[@"username"]];



}

#pragma mark - Textfield Delegate & Helpers
- (void)textFieldSetup
{
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardWillShow:)
                                                 name:UIKeyboardWillShowNotification
                                               object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardWillBeHidden:)
                                                 name:UIKeyboardWillHideNotification
                                               object:nil];

    UITapGestureRecognizer *tap;
    tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)];
    [self.view addGestureRecognizer:tap];
}

- (void)keyboardWillShow:(NSNotification *)note
{
    CGRect keyboardFrameEnd = [[[note userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
    self.messagingBottomConstraint.constant = keyboardFrameEnd.size.height - 24;//Was 48

    [UIView animateWithDuration:0.25 animations:^{
        [self.view layoutIfNeeded];
    }];

    [self scrollToBottom];
}

- (void)keyboardWillBeHidden:(NSNotification *)note
{
    self.messagingBottomConstraint.constant = 0;

    [UIView animateWithDuration:0.25 animations:^{
        [self.view layoutIfNeeded];
    }];

}

- (void)dismissKeyboard
{
    [self.messageTextField resignFirstResponder];
    [self scrollToBottom];
}

- (void)scrollToBottom
{
    //Scroll to bottom
    if (self.messages.count > 0)
    {
        NSIndexPath *indexPath = [NSIndexPath indexPathForRow:self.messages.count - 1 inSection:0];
        [self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
    }
}

#pragma mark - Table View Datasource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    //return self.messages.count;
    NSLog(@"self.messages array - %@",self.messages);
    return [self.messages count];
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [UITableViewCell new];
    id<SINMessage> message = [self.messages[indexPath.row] firstObject];
    MessageDirection direction = (MessageDirection)[[self.messages[indexPath.row] lastObject] intValue];

    if (direction == Incoming)
    {
        cell = [self.tableView dequeueReusableCellWithIdentifier:CELL_ID_RECIPIENT];
        ((RecipientTableViewCell *)cell).message.text = message.text;
    }
    else
    {
        cell = [self.tableView dequeueReusableCellWithIdentifier:CELL_ID_USER];
        ((UsersTableViewCell *)cell).message.text = message.text;
    }
    return cell;
}

#pragma mark - Sending Message
- (IBAction)sendMessage:(id)sender
{
    [self dismissKeyboard];
    NSLog(@"username of recipient - %@",self.selectedUser[@"username"]);

    NSString *outgoingMessage = self.messageTextField.text;
    [delegate sendMessage:outgoingMessage toRecipient:self.selectedUser[@"username"]];


}

- (void)messageDelivered:(NSNotification *)notification
{
    NSString *chatMessage = [[notification userInfo] objectForKey:@"message"];
    [self.messages addObject:chatMessage];
    [self.tableView reloadData];
    [self scrollToBottom];
}

@end

The error is invoked by this line in MessagingViewController.m apparently:

[delegate sinchClientWithUserId:mainUser[@"username"]];

Which is calling this method in AppDelegate:

- (void)sinchClientWithUserId:(NSString *)userId
{

        self.client = [Sinch clientWithApplicationKey: [SINCHAPPKEY]
                                applicationSecret:[SINCHAPPSECRET]
                                  environmentHost:@"sandbox.sinch.com"
                                           userId:userId];
        self.client.delegate = self;

        [self.client setSupportCalling:NO];
        [self.client setSupportMessaging:YES];
        [self.client start];
        [self.client startListeningOnActiveConnection];

}

A few points in case they are relevant:

  1. Xcode 6.3.2, iOS 7.0+

  2. Using Parse and using the stored e-mail username for users as the username for Sinch

  3. Using Crashlytics/Fabric

  4. I show no users created on Sinch dashboard.

Any help is appreciated. Sinch looks like a really powerful tool but I can't seem to get it going. Thanks.

I finally got past this problem by removing the Parse FB utilities and using the -all_load linker flag. The Sinch client now starts and the error no longer appears. I'm not sure what happened to cause the error but appears to be some conflict with Sinch and Parse FB Utils. I had already followed Sinch instructions on loading extra libs and frameworks to resolve any such conflict but apparently that was not enough.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM