Возможно ли иметь самообновляющееся приложение для iPhone?
Возможно ли иметь самообновляющееся приложение для iPhone?
Я верю, что ответ - нет, но я не уверен.
У меня есть приложение на основе базы данных, которое фактически является каталогом продуктов. Я хочу, чтобы база данных была на iPhone пользователей, поэтому каталог можно использовать быстро. Однако периодически содержимое в базе данных меняется.
Я мог бы создать push-уведомление, чтобы сообщить пользователю о готовности обновления базы данных, но было бы лучше, если бы само приложение обновлялось.
5 ответов
Как ответила fluchtpunkt, приложение для iOS может загружать новые данные, просто не может загружать новый код. Многие приложения для iOS, такие как множество клиентов Twitter, в основном загружают и отображают данные.
В случае возникновения проблем у приложения, если его интерфейс не дает понять, что приложение загружает данные. Приложение не должно использовать выделенный тарифный план iPhone без ведома пользователя. Уведомление пользователя может варьироваться от явных уведомлений, включая возможность отмены загрузки, до создания концепции приложения о загрузке данных (например, клиентов Twitter).
Пользователь также должен быть уведомлен, если приложение делится какой-либо информацией с сервером. Приложение может захотеть отправить такие данные для выборочной загрузки определенных данных. Например, приложение может использовать информацию о местоположении, чтобы адаптировать базу данных, загружая только те элементы, которые доступны в регионе, в котором находится устройство. Процесс входа в систему может быть достаточным уведомлением, если данные относятся к конкретной учетной записи.
До тех пор, пока вам не нужно ничего менять внутри пакета приложения, это возможно. Просто сохраните ваш контент в каталоге документов.
И, конечно, вы можете обновить свою собственную базу данных.
Невозможно загрузить исполняемый файл на iPhone, хотя стоит отметить, что вы можете загружать пакеты ресурсов динамически. Если вы используете IB для создания своих представлений, вы можете создать совершенно новое представление, поместить его в облако и загрузить из приложения. Единственное предостережение в том, что вы можете только обновлять дизайн, но не расширять функциональность.
Для динамической загрузки XIB используйте initWithNibName
метод,
- (id)initWithNibName:(NSString *)nibName bundle:(NSBundle *)nibBundle
и передать в динамически загруженный пакет.
На Mac можно иметь пакеты, содержащие исполняемый код, который можно загружать динамически, но не на iPhone. Существует конфигурация Plist с именем NSPrincipalClass
для Mac, но, к сожалению, пока не для iPhone.
Мое приложение использует базу данных SQLite и обновляет ее. При каждом запуске (или выходе из приостановленного режима) он подключается к моему веб-серверу и проверяет наличие новой базы данных. Для аутентификации базы данных сначала загружается только файл, содержащий сумму MD5 онлайн-базы данных, и вычисляется сумма MD5 базы данных на телефоне. Только если суммы отличаются, новая база данных будет загружена. У этого есть хороший побочный эффект, который поддерживает низкий трафик.
Пример кода для расчета суммы MD5:
#define CHUNK_SIZE 16384
#import <CommonCrypto/CommonDigest.h>
+ (NSString *)md5SumForFileAtPath:(NSString *)path {
NSFileHandle *handle = [NSFileHandle fileHandleForReadingAtPath:path];
CC_MD5_CTX md5;
CC_MD5_Init(&md5);
BOOL done = NO;
while(!done)
{
NSData* fileData = [handle readDataOfLength:CHUNK_SIZE];
CC_MD5_Update(&md5, [fileData bytes], [fileData length]);
if ([fileData length] == 0) done = YES;
}
unsigned char result[CC_MD5_DIGEST_LENGTH];
CC_MD5_Final(result, &md5);
NSString *digest = [NSString stringWithFormat:@"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
result[0], result[1], result[2], result[3],result[4],
result[5], result[6], result[7], result[8], result[9],
result[10], result[11], result[12], result[13],
result[14], result[15]
];
XLog("Checksum for file %@: %@", path, digest);
return digest;
}
Однако загрузка всей базы данных является хорошим решением, только если база данных не слишком велика. Кроме того, я распаковал базу данных и распаковал ее после загрузки.
#import <zlib.h>
+ (void)gunzipFileAtPath:(NSString *)zippedPath toPath:(NSString *)unzippedPath {
gzFile file = gzopen([zippedPath UTF8String], "rb");
FILE *dest = fopen([unzippedPath UTF8String], "w");
unsigned char buffer[CHUNK_SIZE];
int uncompressedLength;
while (uncompressedLength = gzread(file, buffer, CHUNK_SIZE) ) {
if(fwrite(buffer, 1, uncompressedLength, dest) != uncompressedLength || ferror(dest)) {
NSLog(@"error writing data");
}
}
fclose(dest);
gzclose(file);
}
Прекрасно показывать только индикатор сетевой активности в строке состояния и не использовать индикатор выполнения или другой индикатор. Если база данных телефона обновлена, я даже не уведомляю пользователя, так как это ненужная информация и будет только отвлекать его. Однако, если есть обновление, я исчезаю в наложении строки состояния и отображаю информацию в течение нескольких секунд. По отзывам моих пользователей я могу сказать, что они очень ценят это решение.
Не забывайте, что вы добавляете криптографию, вычисляя сумму MD5. Вы должны указать это Apple при загрузке вашего следующего обновления. Мне оставалось ответить только на один вопрос и сказать, что я использую шифрование только для аутентификации. Приложение было одобрено без проблем.
Вы можете сделать это с помощью push-уведомлений, кроме того, что вы можете установить таймер, который будет загружать новые данные каждый раз, но проблема в том, что приложение должно быть открыто все время. В iOS 4 есть локальное уведомление, которое может отправлять уведомления пользователю даже когда приложение закрыто