Обмен данными между двумя или более приложениями iPhone


79

Можно ли обмениваться данными между двумя приложениями на одном устройстве?

Или я могу разрешить другому приложению использовать информацию / данные моего приложения или любым другим способом?

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

Это всего лишь простой пример, а не реальный сценарий.

Ответы:


38

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

В последних выпусках IOS они немного ослабили это. Например, в руководстве по программированию iOS теперь есть раздел о передаче данных между приложениями, когда одно приложение запрашивает определенный префикс URL, а затем другие приложения ссылаются на этот URL. Итак, возможно, вы настроили свое приложение для обработки событий так, чтобы оно отвечало на URL-адреса "event: //" так же, как веб-сервер отвечает на URL-адреса "http: //".

Документация Apple об этом подходе находится здесь .

Загляните в раздел «Реализация пользовательских схем URL».


Спасибо, это именно то, что я ищу.
Камлешвар

Можно ли таким образом обмениваться большими данными, например файлами?
AlikElzin-kilaka

2
Если вы читаете это далеко, не забудьте проверить ответ @siejkowski ниже, так как он более актуален.
mahboudz

1
Также стоит отметить ответ @ chintan-maddy-ramani.
mahboudz

2
Да, с тех пор, как я написал этот ответ, было добавлено много лучших способов. На старый вопрос есть старый ответ!
baudot

103

В изолированном мире разработки iOS обмен данными между приложениями может оказаться затруднительным. Поскольку разработчики iOS не могут обмениваться данными напрямую через файловую систему , им необходимо найти альтернативные решения для своих приложений. Некоторые распространенные решения включают:

  • UIDocumentInteractionController

  • UIActivityViewController

  • Общий доступ к связке ключей

  • Собственная схема URL

  • Веб-сервис

  • iCloud API


UIDocumentInteractionController:

Позволяет пользователю открывать документ в любом другом приложении, которое зарегистрировано как способное обрабатывать конкретный документ Uniform Type Identifier (UTI) .

UIDocumentInteractionController использовался в прошлом как средство открытия документа в других приложениях на устройстве, например, для открытия вложений электронной почты из почтового приложения.

UIDocumentInteractionController

К сожалению, пользовательский интерфейс UIDocumentInteractionController отображает только шесть приложений .

Вы не можете гарантировать, что ваше приложение появится в списке. Хотя UIDocumentInteractionController не является устаревшим, UIActivityViewController предоставляет более гибкую замену , начиная с iOS 6.0.

Доступность: iOS 3.2+

Плюсы:

  • Позволяет обмениваться общими типами данных с широким спектром приложений.

Минусы:

  • Позволяет управлять типом данных, отправляемых в UIDocumentInteractionController, но не адресами.

  • Требуется дополнительное взаимодействие с пользователем.

  • Ограниченное количество адресатов данных может привести к тому, что ваше приложение не будет отображаться в списке.


UIActivityViewController:

Позволяет пользователю выполнять ряд действий с массивом данных.

Например, они могут распечатывать, отправлять по электронной почте, копировать, публиковать в социальных сетях или открывать в другом приложении.

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

UIActivityController

Доступность: iOS 6.0+

Плюсы:

  • Отлично подходит для обмена общими типами данных с широким спектром приложений и социальных сетей.

  • Может предоставить массив элементов для приложения к действию. Объекты должны соответствовать протоколу UIActivityItemSource.

  • Имеет возможность устанавливать исключенные типы активности.

  • Пользовательский интерфейс разбиения на страницы позволяет использовать больше мест назначения данных, чем UIDocumentInteractionController.

Минусы:

  • Вы должны определить настраиваемый тип действия, чтобы ограничить назначение «Открыть в…» для общих типов данных.

  • Требуется дополнительное взаимодействие с пользователем.


Общий доступ к связке ключей:

Позволяет безопасно хранить данные в общей связке ключей, к которой могут получить доступ другие приложения, входящие в набор приложений.

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

Пример использования общего доступа к связке ключей в действии. См . Пример кода Apple GenericKeychain .

Общая цепочка для ключей

Доступность: iOS 3.0+

Плюсы:

  • Безопасный доступ к данным.

Минусы:

  • Вы можете обмениваться данными только между приложениями, которые имеют общий префикс идентификатора приложения.

  • API Связки ключей в симуляторе iOS поступает из OS X, API которой отличается от API устройства iOS.


Пользовательская схема URL:

Позволяет передавать данные между приложениями с помощью простых URL-адресов.

Собственная схема URL

Доступность: iOS 3.0+

Плюсы:

  • Сетевое подключение не требуется.
  • Отлично подходит для небольших объемов данных, которые можно легко закодировать в экранированный законный URL.

Минусы:


iCloud API:

Все знают, что такое iCloud, плюсы и минусы, так что объяснений этому нет.

Но кто-то может спросить, как можно обмениваться данными между приложениями внутри одного устройства? Есть некоторые обходные пути для этого.

iCloud

Это возможно, потому что идентификатор, который используется для iCloud, отличается от идентификатора пакета, поэтому можно обмениваться изображениями, видео и другими документами.

Чтобы узнать больше, смотрите обсуждение этой темы


Веб-сервис:

Синхронизируйте данные через стороннюю (например, Dropbox) или созданную на заказ веб-службу.

веб-сервис

Доступность: iOS 2.0+

Плюсы:

  • Полезно для обмена и распространения больших объемов данных.

Минусы:

  • Требуется подключение к сети.
  • Накладные расходы на реализацию веб-службы.

Справка


3
нравится развернутый ответ и использование графики
coolharsh55

1
Вы также должны упомянуть UIPasteboardAPI.
Евгений Каркан

@EvgenyKarkan - Пожалуйста, не стесняйтесь редактировать пост :)
Durai Amuthan.H

54

С iOS 8 я успешно получил доступ к той же папке, используя « Функциональность группы приложений». Я расширяю ответ @siejkowski.

Примечание: он будет работать только с той же учетной записью разработчика.

Для этого вам необходимо выполнить следующие шаги.

  1. Сначала включите «Группы приложений» в своей учетной записи разработчика.
  2. Создать профиль обеспечения. и используйте это.

Теперь вам нужно создать два приложения. Имя образца

  1. Demo_Share_One
  2. Demo_Share_Two

Теперь мы копируем изображения из Demo_Share_One в папку общего доступа, которая создается по умолчанию, когда вы включаете группы приложений и запускаете приложение. и будет получать доступ ко всем этим изображениям из Demo_Share_Two .

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

Добавьте метод ниже в обоих приложениях, чтобы получить относительный путь URL-адреса общей папки.

- (NSString *) getSharedLocationPath:(NSString *)appGroupName {
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSURL *groupContainerURL = [fileManager containerURLForSecurityApplicationGroupIdentifier:appGroupName];
    return [groupContainerURL relativePath];
}

Теперь мы копируем изображения из Bundle из Demo_Share_One

-(IBAction)writeImage:(id)sender
{
    for (int i = 0; i<15; i++) 
    {
        NSString *strSourcePath = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"hd%d",i+1] ofType:@"jpg"];
        NSString *strDestinationPath = [[self getSharedLocationPath:@"group.filesharingdemo"] stringByAppendingPathComponent:[NSString stringWithFormat:@"hd%d",i+1]] ;

        BOOL filewrite = [[NSFileManager defaultManager]copyItemAtPath:strSourcePath toPath:strDestinationPath error:nil];
        if (filewrite)
            NSLog(@"File write");
        else
            NSLog(@"can not write file");
    }
}

Теперь в Demo_Share_Two для доступа к этим изображениям

NSString *pathShared = [[self getSharedLocationPath:@"group.filesharingdemo"] stringByAppendingPathComponent:[NSString stringWithFormat:@"hd%d.jpg",number]];
NSLog(@"%@",pathShared);
//BOOL fileExist = [[NSFileManager defaultManager] fileExistsAtPath:pathShared];
imgView.image = [UIImage imageWithContentsOfFile:pathShared];

И теперь вы получите все изображения, которые вы пишете, из Demo_Share_One .

Итак, с этого момента, если вы хотите поделиться этой папкой, два вашего третьего приложения. просто добавьте это приложение в свою группу. Поэтому слишком легко получить доступ к одним и тем же элементам в ваших нескольких приложениях.

если вы не включите группы приложений в своем AppID, вы получите [self getSharedLocationPath: @ "group.filesharingdemo"] - null.

Спасибо Apple за функцию обмена элементами из ваших собственных приложений . Удачного кодирования. :)


s / getSharedLocationPath: / sharedLocationPathForAppGroup: / :-)
Иван Вучица

1
@ChintaN -Maddy- Ramani может ли общий путь расположения содержать sqlLite или realm db? Нужны ли для этого расширения?
user2363025

@ user2363025 Может быть, да. Ты можешь попробовать. Я просто пробовал с изображениями. возможно, вы можете скопировать туда базу данных.
ChintaN -Maddy- Рамани

@ ChintaN-Maddy-Ramani. Я получаю сообщение об ошибке: Domain = NSCocoaErrorDomain Code = 512 «Файл« 1FAA9B86-E775-4A2D-A2D6-A442C8A9A8FA »не может быть сохранен в папке« AppGroup ». UserInfo = {NSFilePath = / частный / вар / мобильный / Контейнеры / Shared / AppGroup / 1FAA9B86-E775-4A2D-A2D6-A442C8A9A8FA, NSUnderlyingError = 0x282202250 {Error Domain = NSPOSIXErrorDomain Code = 21 "Является каталог"}}
Ананд Пракаш


18

Начиная с iOS 8, вы можете легко обмениваться данными между приложениями, если они находятся в общей группе приложений.

Документация Apple лучше всего объясняет это в контексте расширений: https://developer.apple.com/library/prerelease/ios/documentation/General/Conceptual/ExtensibilityPG/ExtensionScenarios.html

В основном вам необходимо:

  1. Определите идентификатор группы приложений (в разделе « Сертификаты, идентификаторы и профили » Центра участников программы Apple Developer Program).
  2. Включите возможность групп приложений, указав указанный выше идентификатор группы приложений для каждого приложения, которое должно обмениваться данными (это можно сделать либо в Xcode: Target -> Capabilities, либо в Центре участников ).
  3. Используйте один из двух API для доступа к общему контейнеру.

Первый API основан на NSUserDefaults:

NSString *appGroupId = @"group.my.group.id";

NSUserDefaults *myDefaults = [[NSUserDefaults alloc] 
                    initWithSuiteName:appGroupId];

[myDefaults setObject:@"foo" forKey:@"bar"];

Второй API основан на NSFileManager. Это просто общая папка, к которой вы можете получить доступ после получения ее URL:

NSString *appGroupId = @"group.my.group.id";

NSURL *sharedFolderURL = [[NSFileManager defaultManager] 
                           containerURLForSecurityApplicationGroupIdentifier:appGroupId];

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

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


Я прошел через ваши шаги и получил общий URL. но как поместить изображение на этот путь. Я добавляю свое имя изображения и записываю данные. затем я пытаюсь восстановить, но не могу вернуть изображение.
ChintaN -Maddy- Рамани 01

Я успешно записал все изображения из app1 и получил все изображения из app2 с помощью группы приложений. Благодарю . +1 :).
ChintaN -Maddy- Рамани 01

Могу ли я присоединить стороннее приложение к моей группе (по выбору) или все приложения должны быть из одной учетной записи разработчика?
DwarDoh

@DwarDoh он должен быть из той же учетной записи разработчика.
ChintaN -Maddy- Рамани

14

Возможен обмен данными между приложениями? Да, именно так!

Используйте UIPasteBoard, доступный в iOS 3.0, документация доступна здесь . Документы Apple говорят:

Класс UIPasteboard позволяет приложению обмениваться данными внутри приложения или с другим приложением, используя общесистемные или специфичные для приложения монтажные панели.

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


Большой! Это выглядит как жизнеспособный способ обмена данными между приложениями.
trusktr

1
UIPasteboard звучит как хорошее решение для обмена небольшими данными, например, для копирования и вставки строк. Есть ли возможность обмениваться файлами между приложениями?
AlikElzin-kilaka

1
@ AlikElzin-kilaka, да, тоже поддерживает NSData.
Евгений Каркан

4

Вы можете использовать настраиваемую схему URL-адресов для доступа к данным из одного приложения в другое. Для получения дополнительной информации перейдите по указанной ниже ссылке -

http://iosdevelopertips.com/cocoa/launching-your-own-application-via-a-custom-url-scheme.html


2
«Данные доступа» здесь вводят в заблуждение. Ссылка относится к статье, в которой некоторые параметры передаются приложению в самом URL.
DonSteep

3

Обратите внимание, что совместное использование данных между приложениями через UIPasteBoard работает только для приложений в одной группе приложений в iOS7. Как говорят яблоки:

+ [UIPasteboard pasteboardWithName: create:] и + [UIPasteboard pasteboardWithUniqueName] теперь уникальны для данного имени, чтобы разрешить доступ к монтажному столу только тем приложениям в той же группе приложений. Если разработчик попытается создать монтажный стол с именем, которое уже существует, и они не являются частью того же набора приложений, он получит свой собственный уникальный и личный монтажный стол. Обратите внимание, что это не влияет на предоставляемые системой монтажные панели, общие и поиск.


Что Apple подразумевает под «одной и той же группой приложений»?
Magic Bullet Дэйв

2
@MagicBulletDave Приложения с одинаковым идентификатором Bundle Seed ID.
MasterBeta

Класс UIPasteboard позволяет приложению обмениваться данными внутри приложения и с другим приложением. Чтобы поделиться данными с любым другим приложением, вы можете использовать общесистемные монтажные панели; для обмена данными с другим приложением, у которого есть тот же идентификатор группы, что и у вашего приложения, вы можете использовать специальные области монтажа.
тестирование

2

Если вы не против подключения к сети, вы можете реализовать для этого специальный веб-сервис или использовать облачный сервис. Сам iCloud здесь не принесет особой пользы; это позволяет вам обмениваться данными только между одним и тем же приложением на разных устройствах. Вы можете прочитать об iCloud здесь .

Без использования сети вы можете использовать « быстрое переключение приложений » для передачи ограниченного объема данных между приложениями с помощью кодирования URL. Фактический объем передаваемых данных я не знаю, но я уверен, что он будет очень ограниченным.

В этом случае лучше всего подходят ответы JugsteR и baudot.


Привет, psoft, не могли бы вы подробнее рассказать о совместном использовании iCloud, который вы объяснили здесь в двух строках
Винаяка Карджиги

Я читал, что идентификатор iCloud не должен совпадать с идентификатором пакета приложения, и поэтому совместное использование iCloud будет вариантом.
тестирование

Внутри стандартного URL-адреса можно передать 64 КБ данных. Это действительно хорошо работает. Если у вас не слишком много данных, вы можете зашифровать / base64 для большей безопасности.
igraczech


-4

Нет. Вам нужно будет использовать какое-то облачное решение.


Насколько я знаю, iCloud предназначен для синхронизации данных на одном устройстве с другими устройствами. Если вы знаете какие-либо способы обмена данными между приложениями на устройстве, пожалуйста, поделитесь ими.
Durai Amuthan.H

2
dbarjkovic, вы правы, мы могли бы использовать облачное решение для синхронизации данных между приложениями, поскольку идентификатор, используемый для iCloud, отличается от идентификатора пакета и его вполне возможно. вот ссылка, чтобы убедиться, что stackoverflow.com/a/8882763/730807 . Проголосуйте за ваш ответ.
Durai Amuthan.H

Почему этот ответ отклонен? Это правильный ответ, но для этого необходимо получить более подробную информацию из документации и привести несколько примеров
Basheer_CAD
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.