Буферы протокола Google для iOS

Является метасинтактической статической библиотекой для iOS.,

http://code.google.com/p/metasyntactic/wiki/ProtocolBuffers

., совместим с обычными старыми С++ скомпилированными прототипами? Я не хочу использовать составной компилятор, который генерирует Obj-C.

Есть ли способ скомпилировать библиотеку, предоставленную Google для iOS?

Ответ 1

Ok. Похоже, что метасинтаксическая библиотека (или любая другая сторонняя библиотека) в этом случае не нужна. Вы можете просто добавить источник Google непосредственно в свой проект. Я нашел следующий ответ от Никола Ферруцци в группе обсуждения google.,.

Оригинальный ответ здесь.,

http://groups.google.com/group/protobuf/browse_thread/thread/ca4218d7db144252

Содержание этого ответа приведено ниже с изображениями, чтобы сделать постоянную запись...


ИЗМЕНИТЬ

С тех пор, как мы попробовали это снова сегодня вечером, мне понадобилось еще несколько шагов в дополнение к приведенным ниже (это работает с protobuf 2.5.0).

  • Вам нужно будет установить ссылку на libz.dylib. Вы устанавливаете это в "Фазы сборки" > "Связывание двоичных файлов с библиотеками".
  • Чтобы легко удалить все связанные с unit test вещи, используйте следующую команду из оболочки в каталоге google find . -name "*unittest*" -exec rm -rf {} \;
  • Также удалите папку с именем testing
  • комментарий #include <google/protobuf/testing/googletest.h> в stringprintf.cc
  • Теперь внимательно следуйте приведенным ниже инструкциям, и все должно работать нормально.

Я использую последнюю версию в своем приложении.. вам действительно не нужно objc direct если вы знакомы с С++, есть только одна точка, где вам нужно перейти от std::string к NSData и наоборот. И это довольно простой.

Чтобы скомпилировать и протестировать самый простой способ, который я обнаружил, это просто импортировать весь каталог google в моем собственном проекте:) (во второй раз вы можете создайте свою собственную структуру, но для тестирования эта процедура просто работает)

  • скачать последнюю версию
  • autogen настроить и сделать так, как будто вы просто строили для macosx (вам нужны инструменты командной строки). Таким образом, вы в конечном итоге с протоком
    двоичный и библиотека для macosx (что вам не нужно)
  • откройте проект iOS Xcode.
  • добавьте "новый файл" в свой проект и выберите каталог google
  • добавить каталог заголовков google в ваши дополнительные каталоги include
  • добавить config.h из каталога protobuffer src в ваше приложение.
  • из группы google удаляет все, что содержит unitest:)
  • из группы google удалить компилятор и java файл;

Вы должны иметь возможность компилировать без какой-либо ошибки связывания. Чтобы дать вам идея заключается в том, что я непосредственно компилирую

enter image description here

Затем вы можете использовать protoc для генерации исходных файлов С++ для вашего протокол. Чтобы использовать их с objc, вам нужно переименовать свой источник в file "mm", тогда вы можете сделать что-то вроде

ДЛЯ СЕРИАЛИЗАЦИИ NSDATA

скажем, ваше сообщение называется Packet

- (NSData *)getDataForPacket:(Packet *)packet { 
    std::string ps = packet->SerializeAsString(); 
    return [NSData dataWithBytes:ps.c_str() length:ps.size()]; 

ЧИТАТЬ ИЗ NSDATA

- (Packet *)getPacketFromNSData:(NSData *)data { 
  char raw[[data length]]; 
  Packet *p = new Packet; 
  [data getBytes:raw length:[data length]]; 
  p->ParseFromArray(raw, [data length]); 
  return p; 

}

Ответ 2

Вы можете добавить поддержку буферов протокола Google в проект Xcode 5 с использованием Cocoapods, добавив следующую строку в ваш подфайл.

pod 'GoogleProtobuf', '~> 2.5.0'

Это поместит версию протобуфа С++ в Pod для вашего проекта. Он также добавит компилятор protoc в папку Pods/GoogleProtobuf/bin/protoc в вашем проекте.

В проекте можно создать правило пользовательской сборки, которое автоматически преобразует файлы .proto в файлы .ph.{h,cc}. Вот как я это сделал:

Установите правило сборки для "Обработать исходные файлы с именами, соответствующими: *.proto Использование Custom Script". script должен включать следующее:

cd ${INPUT_FILE_DIR}
${SRCROOT}/Pods/GoogleProtobuf/bin/protoc --proto_path=${INPUT_FILE_DIR} ${INPUT_FILE_PATH} --cpp_out=${INPUT_FILE_DIR}/cpp

Задайте выходные файлы следующим образом:

$(INPUT_FILE_DIR)/cpp/$(INPUT_FILE_BASE).pb.h
$(INPUT_FILE_DIR)/cpp/$(INPUT_FILE_BASE).pb.cc

Любые .proto файлы, которые вы включаете в свой проект, теперь будут автоматически преобразованы в С++ и затем скомпилированы как часть вашей сборки.

Ответ 3

РЕДАКТИРОВАТЬ: я ответил ранее, но был удален модератором. Поэтому я включил некоторый код из учебника.

Учебник, который почти такой же, как и выше, - Использование буферов протокола Google в Objective-C на iOS и Mac

Следуйте инструкциям, приведенным в ответе learnvst, и отсылайте комментарии к ошибкам. Я выполнил те же самые шаги, кроме

добавить каталог заголовков google в ваши дополнительные каталоги include Я добавил каталог src/ в пути поиска заголовков, а не в каталог google.

Кроме того, когда я сделал #import xyz.pb.h, проект не строился. Когда я переименовал свой файл .m в .mm, я смог создать. Этот момент упоминается в учебнике очень тонко: P.

В принципе, любой файл .m, который импортирует любой файл .pb.h, должен быть переименован с расширением .mm

Вот некоторый контент из учебника -

ФАЙЛ ПРОТОКА

package kotancode;

enum ZombieType {
    SLOW = 0;
    FAST = 1;
}

message ZombieSighting {
    required string name = 1;
    required double longitude = 2;
    required double latitude = 3;
    optional string description = 4;
    required ZombieType zombieType = 5 [default = SLOW];
}

ZombieSightingMessage.h

// -- ZombieSightingMessage.h - note my C++ object is not in the public interface.
#import <Foundation/Foundation.h>

@interface ZombieSightingMessage : NSObject
- (void)doSomething;
@end

ZombieSightingMessage.mm

// -- ZombieSightingMessage.mm
#import <UIKit/UIKit.h>
#import "ZombieSightingMessage.h"
#import "zombie.pb.h"

@implementation ZombieSightingMessage

- (void)doSomething {
    // Doing random stuff with a UIView here to show the mixing
    // of C++ and Objective-C/Cocoa syntax in the same file...
    UIView *uiView = [[UIView alloc] init];
    [uiView setCenter:CGPointMake(20, 10)];

    // instantiate my protobuf-generated C++ class.
    kotancode::ZombieSighting *zombieSighting = new kotancode::ZombieSighting();
    zombieSighting->set_name("Kevin");
    zombieSighting->set_description("This is a zombie");
    zombieSighting->set_latitude(41.007);
    zombieSighting->set_longitude(21.007);
    zombieSighting->set_zombietype(kotancode::ZombieType::FAST);

    // Some small tomfoolery required to go from C++ std::string to NSString.
    std::string x = zombieSighting->DebugString();
    NSString *output = [NSString stringWithCString:x.c_str() encoding:[NSString defaultCStringEncoding]];
    NSLog(@"zombie: %@", output);

    // Instantiate another zombie from the previous zombie raw bytes.
    NSData *rawZombie = [self getDataForZombie:zombieSighting];
    kotancode::ZombieSighting *otherZombie = [self getZombieFromData:rawZombie];

    // Dump the second zombie so we can see they match identically...
    NSString *newOutput = [NSString stringWithCString:otherZombie->DebugString().c_str() encoding:[NSString defaultCStringEncoding]];
    NSLog(@"other zombie: %@", newOutput);

    // Grimace all you want, but this is C++ and we need to clean up after ourselves.
    free(zombieSighting);
    free(otherZombie);

}

// Serialize to NSData. Note this is convenient because
// we can write NSData to things like sockets...
- (NSData *)getDataForZombie:(kotancode::ZombieSighting *)zombie {
    std::string ps = zombie->SerializeAsString();
    return [NSData dataWithBytes:ps.c_str() length:ps.size()];
}

// De-serialize a zombie from an NSData object.
- (kotancode::ZombieSighting *)getZombieFromData:(NSData *)data {
    int len = [data length];
    char raw[len];
    kotancode::ZombieSighting *zombie = new kotancode::ZombieSighting;
    [data getBytes:raw length:len];
    zombie->ParseFromArray(raw, len);
    return zombie;
}

@end

EDIT: я использую Xcode 4.5. Даже после того, как я выполнил все шаги, я получил ошибку компоновщика.

символы, не найденные для архитектуры i386

Из-за этого я не смог запустить код на симуляторе. Но он работал на самом устройстве

Ответ 4

Я предполагаю, что на основе фактического вопроса мой комментарий стоит опубликовать в качестве ответа:

Я использую слегка измененную версию генерации кода Obj, предоставленную Booyah

Он поддерживает повторяющиеся поля из коробки, но для использования быстрого перечисления ObjC вам необходимо преобразовать тип PBArray (в основном типизированный c-буфер) в массив NSObjects, который он представляет, либо сообщение NSNumber или protobuf объекты. Вы можете увидеть пример обновленного кода быстрого перечисления в это изменение:. Вы также можете добавить категорию для PBArray, вызываемой toObjects.

Я просто отмечаю сгенерированный код -fno-objc-arc, но вы можете получить поддержку дуги и 2.5 из запросов booyah pull.

Направления очень хороши для настройки, но если людям нужны более явные инструкции по используемой категории, как я создал плагин protobuf-objc, как получить поддержку префиксов класса (например, IXMyProtoMessage вместо MyProtoMessage) или как я генерировать код, дайте мне знать, и я постараюсь выделить время, чтобы написать сообщение. Я использую его s > 50 прото файлами с большим количеством зависимостей между проектами.

Слабость библиотеки заключается в том, что она не включает типичное отражение APP Protobuf в сгенерированном коде, поэтому выполнение чего-то вроде преобразования сообщения в NSDictionary должно было бы сделать некоторые хакерские вещи в среде выполнения objC (код doesn ' t следуйте типичным требованиям KV) или напишите генератор пользовательского кода из протос, у которого есть отражение api (я сделал это с python + jinja2). Или - еще лучше и с подобной сложностью, добавьте отражение apis в генератор кода;).