0

I am currently using google's protocol buffers. It works painlessly between Java and C#, however I am running into problems trying to achieve the same use with Obj-c.

The Java WS returns a byte[]. The code that uses the protocol buffer API is simple enough:

productGroup.toByteArray();

I am able to recreate the object with Skeet's C# port, using:

byte[] result = searchWebService.SearchProductsProtocolBuffer(search);
ProductProtoGroup products = ProductProtoGroup.ParseFrom(result);

However, on the obj-c side, I am struggling to work with the return value.

The NSString I receive from the same web service RPC is this:

CmYKEzgwMDAwMUFELTEzMjUyNzk5MTQySUZPT0QgJiBCRV...

I'm not quite sure what to do with this, because I don't know what it is, save it was generated from an array of bytes. I tried parsing it directly to NSData using

NSData* data = [returnValue dataUsingEncoding:NSUTF8StringEncoding];

but on [ProductProtoGroup parseFromData:data];, I get an InvalidProtocolBuffer

I've checked on the Java side what byte string/hexadecimal representations of the original byte[], and it doesn't match the string I receive from the ws.

Hexadecimal is 0-F. Perhaps each byte was converted to a char? No, that doesn't match.

Any help would be appreciated.

Dane

2
  • What is the source value that the mystery NSString is encoding? (e.g. the byte array you get in Java or C#)? Commented Aug 12, 2012 at 22:01
  • What Objective-C port of the protocol buffers are you using? Commented Aug 12, 2012 at 22:29

2 Answers 2

1

With a fresher mind and some helpful comments, I finally got it.

I was wondering how the web service automagically sent a byte[] in Java, then reconstructed it in C# later, and also how to store this message later.

Turns out the string,

CmYKEzgwMDAwMUFELTEzMjUyNzk5MTQySUZPT0QgJiBCRV...

was indeed what was being sent in the soap envelopes. So inbetween creation of a byte[] in Java and transmission, something was happening. Looking at the message handler in C#,

[System.Web.Services.Protocols.SoapDocumentMethodAttribute("", 
    RequestNamespace="x", ResponseNamespace="x", 
    Use=System.Web.Services.Description.SoapBindingUse.Literal, 
   ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
[return: System.Xml.Serialization.XmlElementAttribute("return",
   Form=System.Xml.Schema.XmlSchemaForm.Unqualified, 
   DataType="base64Binary", IsNullable=true)]
public byte[] searchProductProtocolBuffer([System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)] string arg0)
{
   object[] results = this.Invoke("searchProductProtocolBuffer", new object[] {
                    arg0});
   return ((byte[])(results[0]));
}

So base64Binary!, which I admittedly am meeting for the first time. Poking around, Skeet says it is the safest way:

How can I safely convert a byte array into a string and back?

So, knowing the encoding, the solution becomes straight forward. Using the algorithm presented in an answer to this question: How do I do base64 encoding on iphone-sdk?, my final code becomes:

NSString* returnValue = [WebServiceUtil processStringReturnValue:value];
NSData* data = [Encoding base64DataFromString:returnValue];
ProductProtoGroup* products = [ProductProtoGroup parseFromData:data];
Sign up to request clarification or add additional context in comments.

Comments

0

I know very little about Objective C, but an NSString is no byte array. Have you tried converting the NSString to char* using -[NSString UTF8String]?

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.