Обмінюйтесь даними між двома або більше програмами iPhone


79

Чи можливо спільне використання даних між двома програмами на одному пристрої?

Або я можу дозволити якійсь іншій програмі використовувати інформацію / дані моєї програми або будь-яким іншим способом?

Наприклад, перша програма призначена для управління подіями, і я використовую її для збереження якоїсь події. Друга програма призначена для нагадувань, яка отримає дані від іншої програми, щоб нагадати мені про подію.

Це лише простий приклад, а не реальний сценарій.

Відповіді:


38

Історично iPhone намагався запобігти обміну даними між програмами. Ідея полягала в тому, що якщо ви не можете отримати дані іншої програми, ви не можете зробити нічого поганого з цією програмою.

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

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

Загляньте в "Впровадження спеціальних схем URL-адрес".


Дякую, це саме те, що я шукаю.
Kamleshwar

Чи можна таким чином обмінюватися великими даними, наприклад файлами?
AlikElzin-kilaka

2
Якщо ви читаєте це далеко, переконайтеся, що ви перевірили відповідь @siejkowski нижче, оскільки вона є найсучаснішою.
mahboudz

1
Відповідь від @ chintan-maddy-ramani також заслуговує на увагу.
mahboudz

2
Так, з моменту написання цієї відповіді було додано багато кращих способів. Старе питання має стару відповідь!
бодо

103

У ізольованому середовищі розробки iOS обмін даними між програмами може виявитись складним Оскільки розробники iOS не можуть обмінюватися даними безпосередньо через файлову систему , їм потрібно знайти альтернативні рішення для своїх додатків. Деякі загальні рішення включають:

  • UIDocumentInteractionController

  • UIActivityViewController

  • Спільний доступ до брелока

  • Спеціальна схема URL

  • Веб-сервіс

  • iCloud API


UIDocumentInteractionController:

Дозволяє користувачеві відкрити документ у будь-якій іншій програмі, яка реєструє можливість обробки певного документа Uniform Type Identifier (UTI) .

UIDocumentInteractionController раніше використовувався як засіб відкриття документа в інших програмах на пристрої, наприклад, відкриття вкладень електронної пошти з програми Mail.

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-адресу.

Мінуси:

  • Ви повинні закодувати дані в захищену юридичну URL-адресу.

    Примітка: кодування base64 часто застосовується, перетворюючи дані, що піддаються серіалізації, у значення рядка. Однак рядки base64 можуть містити символи, які неприпустимі для використання в URL-адресах. Ви можете розглянути можливість використання base64url. Для отримання додаткової інформації див. Кодування коду за допомогою URL-адреси та безпечного алфавіту імені файлу .


API iCloud:

Всі знають про те, що таке 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 for Share Elements завдяки власним функціоналам додатків . Щасливого кодування. :)


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

1
@ChintaN -Maddy- Ramani, чи може спільний шлях до місцезнаходження містити sqlLite або область db? Чи потрібні для цього розширення?
user2363025

@ user2363025 Можливо, так. Ви можете спробувати. Я просто спробував із зображеннями. можливо, ви можете скопіювати туди базу даних.
ChintaN -Maddy- Ramani

@ 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. Визначення App Group ID (в сертифікатах, Ідентифікатори і профілі розділ Центр - членів для вашої компанії Apple Developer Program.
  2. Увімкніть можливість груп груп додатків із зазначенням вищезазначеного ідентифікатора групи програм для кожної програми, яка потребує зв’язку (це потрібно зробити в Xcode: Ціль -> Можливості або в Центрі учасників ).
  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-адресу. але як поставити Image на цей шлях. я додаю своє ім’я зображення та записую дані. тоді я намагаюся отримати, але не вдалося отримати зображення назад.
ChintaN -Maddy- Ramani

я успішно зробив це, щоб написати всі зображення з app1 і отримати всі зображення з app2 за допомогою групи додатків. Дякую . +1 :).
ChintaN -Maddy- Ramani

Чи можу я приєднати сторонній додаток до моєї групи (за вибором), чи всі програми повинні бути з одного облікового запису розробника?
DwarDoh

@DwarDoh це має бути з того самого облікового запису розробника.
ChintaN -Maddy- Ramani

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 Dave

2
Додатки @MagicBulletDave, які мають однаковий ідентифікатор набору наборів.
MasterBeta

Клас UIPasteboard дозволяє програмі обмінюватися даними всередині програми та з іншою програмою. Для обміну даними з будь-яким іншим додатком ви можете використовувати загальносистемні картони; щоб поділитися даними з іншим додатком, який має той самий ідентифікатор команди, що і ваш додаток, ви можете використовувати спеціальні картонні картони.
тестування

2

Якщо ви не проти потрапити в мережу, ви можете застосувати для цього власну веб-службу або скористатися якоюсь хмарною службою. сам iCloud тут не принесе особливої ​​користі; це дозволяє лише обмінюватися даними між одним і тим же додатком на різних пристроях. Про iCloud ви можете прочитати тут .

Не використовуючи мережу, ви можете скористатися функцією " швидкого переключення додатків " для передачі обмеженого обсягу даних між програмами за допомогою кодування URL. Фактичний обсяг даних, що підлягає передачі, я не знаю, але я впевнений, що це буде дуже обмежено.

Відповіді JugsteR та Бодо найкращі в цьому випадку.


Привіт, psoft, ти можеш докладніше розповісти про спільний доступ до iCloud, який ти пояснив тут у двох рядках
Vinayaka Karjigi

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

Можна перенести 64 кБ даних всередині стандартної URL-адреси. Це насправді працює добре. Якщо у вас недостатньо даних, ви можете зашифрувати / base64 для кращого захисту.
igraczech


-4

Ні. Вам довелося б використовувати якесь хмарне рішення.


Наскільки мені відомо, iCloud призначений для синхронізації даних на одному пристрої з іншими пристроями. Якщо ви знаєте будь-які способи обміну даними між програмами на пристрої, будь ласка, поділіться ними.
Дурай Амутан. H

2
dbarjkovic ти маєш рацію, ми могли б використовувати хмарне рішення для синхронізації даних між програмами, оскільки ідентифікатор, який використовується для iCloud, відрізняється від ідентифікатора пакета і є цілком можливим. ось посилання для підтвердження того, що stackoverflow.com/a/8882763/730807 . проголосуйте за вашу відповідь.
Дурай Амутан. H

Чому ця відповідь проти? Це правильна відповідь, але вона повинна мати більше деталей з документації та наводити кілька прикладів
Basheer_CAD
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.