Sinch iOS — «NSInvalidArgumentException», «-[UIDevice reb_platform]: нераспознанный селектор

Я пытаюсь внедрить Sinch с помощью iOS SDK, и, несмотря на то, что внимательно следую документации и руководствам, я продолжаю получать эту ошибку:

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

Я пробовал следующее:

  1. Удалена структура Sinch и переустановлена ​​последняя версия (3.5.2). Я убедился, что после удаления я удалил из каталога файлов, и все ссылки в «Связанных платформах и библиотеках» в целом и «Связывание двоичных файлов с библиотеками» на этапах сборки не имели ссылок на Sinch перед повторной установкой и убедитесь, что он был скопирован. У меня загружены все необходимые фреймворки [в том числе для конфликтов Parse] (AVFoundation, Security, Audiotoolbox, Bolts, libstc++6.0.9.dylib) и все необходимые флаги компоновщика (-ObjC, -Xlinker, -lc++).

  2. Дважды проверил правильную реализацию делегата Sinch (SINClientDelegate, SINMessageClientDelegate) и переместил всю настройку/реализацию делегата Sinch в AppDelegate, чтобы упростить анализ.

  3. Пробовал работать на реальном устройстве, а также на симуляторе

  4. Изменена настройка приложения Sinch, чтобы мое приложение не требовало аутентификации JS (хотя я не думаю, что это влияет на iOS SDK).

  5. Обыскал весь проект в поисках любой ссылки на reb_platform и не нашел ни одной. Вероятно, это вызов частного метода Sinch в его библиотеке.

Вот мой соответствующий код:

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

Ошибка вызывается этой строкой в ​​MessagingViewController.m, по-видимому:

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

Который вызывает этот метод в 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];

}

Несколько моментов, если они актуальны:

  1. Xcode 6.3.2, iOS 7.0+

  2. Использование Parse и использование сохраненного имени пользователя электронной почты для пользователей в качестве имени пользователя для Sinch

  3. Использование Crashlytics/Fabric

  4. Я не показываю пользователей, созданных на панели инструментов Sinch.

Любая помощь приветствуется. Sinch выглядит как действительно мощный инструмент, но я не могу заставить его работать. Спасибо.


person hlegal    schedule 01.08.2015    source источник
comment
Ни один из кодов, которые вы разместили, не имеет ничего общего с ошибкой. Где вы вызываете метод reb_platform для UIDevice? Имейте в виду, что такого метода не существует (по крайней мере, как это предусмотрено Apple). Вы должны использовать стороннюю библиотеку, которая добавляет этот метод в категорию. Убедитесь, что вы включили правильную структуру, библиотеку или исходный файл для этого метода категории.   -  person rmaddy    schedule 01.08.2015
comment
Да, я проверил весь проект на наличие такого вызова, и ничего не появляется. Это должно быть как-то связано с библиотекой Синча, потому что Rebtel создал ее, и reb-платформа, кажется, подходит, но я дважды проверил структуру и заголовки, и они, похоже, в порядке. Я запустил образец учебника от Sinch, и он работает нормально. Фреймворки и заголовки кажутся одинаковыми.   -  person hlegal    schedule 01.08.2015
comment
Вы получили clientdidstart?   -  person cjensen    schedule 03.08.2015
comment
Я не был. Но я, наконец, решил эту проблему, удалив утилиты Parse FB и используя флаг компоновщика -all_load. Теперь клиент запускается. Теперь я имею дело с другой ошибкой, связанной с нераспознанным селектором [SINMessageRebRTCImpl firstObject], отправленным экземпляру. Сначала я попытаюсь решить самостоятельно, но в противном случае опубликую другую проблему.   -  person hlegal    schedule 03.08.2015
comment
comment
Это не дубликат, поскольку эта проблема характерна для Sinch SDK. Проблема возникла из-за конфликта с Parse FB SDK. Это было не так просто, как убедиться, что для UIDevice вызывается соответствующий метод.   -  person hlegal    schedule 03.08.2015


Ответы (1)


Я, наконец, решил эту проблему, удалив утилиты Parse FB и используя флаг компоновщика -all_load. Теперь клиент Sinch запускается, и ошибка больше не появляется. Я не уверен, что вызвало ошибку, но похоже, что это какой-то конфликт с Sinch и Parse FB Utils. Я уже следовал инструкциям Sinch по загрузке дополнительных библиотек и фреймворков для разрешения любого такого конфликта, но, видимо, этого было недостаточно.

person hlegal    schedule 03.08.2015
comment
У меня была такая же проблема, после добавления других флагов компоновщика она работает нормально. Спасибо - person Nikita Sharma Sahu; 16.08.2016