Forum Xamarin Xamarin.iOS

UITableView.ReloadData() causes some string convertion exception

I have remotely catched some reports from several users and the exception appears in UITableView.ReloadData(), it looks like that:

Partial byte sequence encountered in the input.
Parameter name: string

Unfortunately, my reporting system for now haves no any other data except callstack (seems there's some InnerException, but it is not logged for now), so I have no any other details.

What I can say, is that exception occurs when the table view containing data from iPhone Address Book (ABAddressBook) is being reloaded. The presented data is: first name, last name, company. First and last names are formatted into NSAttributedString (and presented using UILabel), the location is set to Text property of non-attributed UILabel.

This exception is thrown every time (not occasionally!) for a constant set of users, so I may assume there's some 'bad' data gathered from ABPersons (some Chinese names etc.?).

Also I can't reproduce the problem giving those UILabels some really random UTF16 strings instead of a real data on simulator or device.

I also tried giving some random string to SectionIndexTitles, the crash is not able to reproduced such way too.

Did anyone face such kind of problems? Googling only gave me some references to 'giconv.c' file containing such strings, but I'm not sure how could that affect internal iOS UITableView routines behavior.

Posts

  • YuriTikhomirovYuriTikhomirov RUMember ✭✭

    Finally found out the way to reproduce, let's put this down to some UITableViewSource implementation:

        public override string[] SectionIndexTitles (UITableView tableView)
        {
            var rnd = new Random();
            var arry = new string [ 24 ];
            for (int i = 0; i < arry.Length; i++)
                arry[i] = new String( (char)rnd.Next(32, char.MaxValue), 1 );
            return arry;
        }
    

    And we'll get that exception shortly.

    To fix the situation, almost the same code, but...

        [Export ("sectionIndexTitlesForTableView:")]
        public IntPtr mySectionIndexTitles(IntPtr tableView)
        {
            var rnd = new Random();
    
            var arry = new string [ 24 ];
            for (int i = 0; i < arry.Length; i++)
                arry[i] = new String( (char)rnd.Next(32, char.MaxValue), 1 );
    
            var nsa = new NSMutableArray(arry.Length);
            for (int i = 0; i < arry.Length; i++)
                nsa.Add( new NSString(arry[i]) );
    
            return nsa.Handle;
        }
    

    This will work. There's abracadabra in section index titles you'll see, but that won't cause a crash.

    I strongly recommend everyone who use SectionIndexTitles generated from user's content (for example, an indexed contact list from ABPersons) to use hand-wrapped 'mySectionIndexTitles' method instead of the one provided by Xamarin. In other case, soon or later, you and your users will face this crash.

    ps. No inner exception is there. Your reporting system, even it is a perfect one, will only tell 'Partial byte sequence encountered in the input. Parameter name: string' inside UITableView.ReloadData() and nothing else.

    pps. The reason I didn't get a chance to reproduce with 'bad' SectionIndexTitles() before is that I've used [NSString initWithCharacters:(random AllocHGlobal chars) length:(len)] to create that bad strings. I've also used hand-wrapped 'mySectionIndexTitles' method to return the NSArray filled with those strings - instead of standard string [] SectionIndexTitles(). So the real reason is somewhere there in marshalling, trampolines or something else deep in Monotouch that brings the crash-causing conversion of c# string[] to NSArray-of-NSStrings.

  • Thanks! It helped.

Sign In or Register to comment.