Вот универсальный путь:
public static Stream Serialize(object source)
{
IFormatter formatter = new BinaryFormatter();
Stream stream = new MemoryStream();
formatter.Serialize(stream, source);
return stream;
}
public static T Deserialize<T>(Stream stream)
{
IFormatter formatter = new BinaryFormatter();
stream.Position = 0;
return (T)formatter.Deserialize(stream);
}
public static T Clone<T>(object source)
{
return Deserialize<T>(Serialize(source));
}
Я собираюсь ответить на свой вопрос здесь, поскольку, как мне кажется, я понял, в чем проблема. Если у вашего контакта еще НЕТ изображения, при использовании ABPersonSetImageData будут добавлены эскиз и полноразмерный снимок. Если у вашего контакта уже есть полноразмерное изображение, ТОЛЬКО эскиз будет установлен, когда вы используете ABPersonSetImageData.
После того, как вы осознаете это, решение становится очевидным. Я просто удаляю картинку прямо перед ее установкой.
if (image) {
NSData *dataRef = UIImagePNGRepresentation(image);
CFDataRef cfdata = CFDataCreate(NULL, [dataRef bytes], [dataRef length]);
CFErrorRef error;
ABPersonRemoveImageData(person, &error); // <-- clean any image first from ref
ABAddressBookSave(addressBook, &error);
ret = ABPersonSetImageData(person, cfdata, &error);
if (ret) {
ret = ABAddressBookSave(addressBook, &error);
} else {
DebugLog(@"Could not write the image to the person");
}
CFRelease(cfdata);
}
ПРИМЕЧАНИЕ * Это создает квадратную версию полноразмерной картинки. Процесс обрезает верхнюю и нижнюю часть изображения и устанавливает его размер 320x320. Но это работает.
РЕДАКТИРОВАТЬ 09.10.09 Я общался с Apple, и это действительно ошибка в адресной книге. Если вы читаете этот пост, то я предлагаю вам зарегистрировать ошибку в Apple по адресу, чтобы ускорить исправление.