ChatGPT解决这个技术问题 Extra ChatGPT

在两个或多个 iPhone 应用程序之间共享数据

这是否可以在同一设备上的两个应用程序之间共享数据?

或者我可以允许其他应用程序使用我的应用程序的信息/数据或以任何其他方式吗?

例如,第一个应用程序是用于事件管理的,我用它来保存一些事件。第二个应用程序用于提醒,它将从另一个应用程序获取数据以提醒我有关事件的信息。

这只是一个简单的例子,不是真实的场景。


C
Community

在 iOS 开发的沙盒世界中,应用程序之间共享数据可能很困难 由于 iOS 开发人员不能直接通过文件系统共享数据,他们需要为他们的应用程序寻找替代解决方案。一些常见的解决方案包括:

UIDocumentInteractionController

UIActivityViewController

共享钥匙串访问

自定义 URL 方案

网络服务

iCloud API

UIDocumentInteractionController:

允许用户在注册为能够处理特定文档统一类型标识符 (UTI) 的任何其他应用程序中打开文档。 UIDocumentInteractionController 过去曾被用作在设备上的其他应用程序中打开文档的一种方式,例如,从 Mail 应用程序打开电子邮件附件。

https://i.stack.imgur.com/MAuqD.jpg

不幸的是,UIDocumentInteractionController 的 UI 只显示了六个应用程序。您不能保证您的应用程序会出现在列表中。虽然 UIDocumentInteractionController 尚未被弃用,但 UIActivityViewController 从 iOS 6.0 开始提供了更灵活的替代品。

可用性:iOS 3.2+

优点:

允许与广泛的应用程序共享通用数据类型。

缺点:

允许控制发送到 UIDocumentInteractionController 的数据类型,但不能控制目标。

需要额外的用户交互。

有限数量的数据目标可能会导致您的应用程序不显示在列表中。

UIActivityViewController:

允许用户对一组数据执行多项操作。例如,他们可以打印、发送电子邮件、复制、发布到社交媒体或在另一个应用程序中打开。您可以创建自己的 UIActivity 子类来为用户提供自定义服务。

https://i.stack.imgur.com/Mio38.jpg

可用性:iOS 6.0+

优点:

非常适合与各种应用程序和社交媒体共享常见数据类型。

可以提供一系列项目以应用于活动。对象应符合 UIActivityItemSource 协议。

能够设置排除的活动类型。

分页 UI 允许比 UIDocumentInteractionController 更多的数据目的地。

缺点:

您必须定义自定义活动类型以限制常见数据类型的“打开方式...”目标。

需要额外的用户交互。

共享钥匙串访问:

允许您将数据安全地存储到共享钥匙串中,作为一组应用程序的一部分的其他应用程序可以访问该钥匙串。所有共享钥匙串访问权限的应用程序都必须使用相同的应用程序 ID 前缀。有关共享钥匙串访问的示例。请参阅 Apple 的 GenericKeychain 示例代码。

https://i.stack.imgur.com/WiCke.png

可用性:iOS 3.0+

优点:

安全访问数据。

缺点:

您只能在共享公共应用 ID 前缀的应用之间共享数据。

iOS Simulator 上的 Keychain API 来自 OS X,与 iOS 设备的 API 不同。

自定义 URL 方案:

允许数据使用简单的 URL 在应用程序之间传递。

https://i.stack.imgur.com/bv4X9.png

可用性:iOS 3.0+

优点:

无需网络连接。

非常适合您可以轻松编码为转义的合法 URL 的少量数据。

缺点:

您必须将数据编码为转义的合法 URL。

注意: base64 编码已经看到了将可序列化数据转换为字符串值的常见用途。但是,base64 字符串可能包含在 URL 中使用无效的字符。您可以考虑使用 base64url。 See Base 64 Encoding with URL and Filename Safe Alphabet 了解更多信息。

iCloud API:

每个人都知道什么是 iCloud,优点和缺点,所以没有更多的解释。但有人可能会问,如何在单个设备内的应用程序之间共享数据,有一些解决方法可以实现这一点。

https://i.stack.imgur.com/Q4Gyi.jpg

这是可能的,因为用于 iCloud 的标识符与捆绑标识符不同,因此可以共享图像、视频和其他文档。要了解更多信息,请参阅有关此主题的讨论

网络服务:

通过第三方(例如 Dropbox)或定制的网络服务同步数据。

https://i.stack.imgur.com/p4gPZ.jpg

可用性:iOS 2.0+

优点:

对于共享和以其他方式分发大量数据很有用。

缺点:

需要网络连接。

Web 服务实现开销。

Reference


喜欢广泛的答案和图形的使用
您还应该提及 UIPasteboard API。
@EvgenyKarkan - 请随时编辑帖子:)
C
ChintaN -Maddy- Ramani

从 iOS 8 开始,我已经成功地使用“应用程序组功能”访问了相同的文件夹。我正在扩展@siejkowski 的答案。

注意:它只适用于同一个开发者帐户。

为此,您必须按照以下步骤操作。

首先从您的开发者帐户启用“应用程序组”。生成配置文件。并使用它。

现在您必须创建两个应用程序。样品名称

Demo_Share_One Demo_Share_Two

现在我们将图像从 Demo_Share_One 复制到共享文件夹,该文件夹在您启用 App Groups 并运行应用程序时默认创建。并且将从 Demo_Share_Two 访问所有这些图像。

您必须使用设置为您的开发者帐户的组名。让我们说 group.filesharingdemo

在两个应用程序中添加以下方法以获取共享文件夹 url 的相对路径。

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

现在我们正在从 Demo_Share_One 的 Bundle 中复制图像

-(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"] 为空。

感谢 Apple 从您自己的应用程序功能中共享元素。快乐编码。 :)


s/getSharedLocationPath:/sharedLocationPathForAppGroup:/ :-)
@ChintaN -Maddy- Ramani 共享位置路径可以包含 sqlLite 或领域数据库吗?为此需要扩展吗?
@user2363025 也许是的。你可以试试。我只是尝试使用图像。也许你可以在那里复制数据库。
@ChintaN-Maddy-Ramani。我收到以下错误:Domain=NSCocoaErrorDomain Code=512“文件“1FAA9B86-E775-4A2D-A2D6-A442C8A9A8FA”无法保存在文件夹“AppGroup”中。” UserInfo={NSFilePath=/private/var/mobile/Containers/Shared/AppGroup/1FAA9B86-E775-4A2D-A2D6-A442C8A9A8FA, NSUnderlyingError=0x282202250 {错误域=NSPOSIXErrorDomain Code=21“是目录”}}
A
AlexVogel

从历史上看,iPhone 曾试图阻止应用程序之间的数据共享。这个想法是,如果你无法获取另一个应用程序的数据,你就不能对那个应用程序做任何坏事。

在最近的 IOS 版本中,他们稍微放松了一点。例如,iOS 编程指南现在有一节介绍通过让一个应用程序声明某个 URL 前缀,然后让其他应用程序引用该 URL,在应用程序之间传递数据。因此,也许您将您的事件应用程序设置为回答“event://”网址,就像网络服务器回答“http://”网址一样。

Apple 对这种方法的文档是 here

查看“实施自定义 URL 方案”下的内容。


谢谢,这正是我正在寻找的。
是否可以通过这种方式共享大数据,例如文件?
如果您正在阅读本文,请务必查看下面的@siejkowski 回复,因为它是最新的。
@chintan-maddy-ramani 的回应也值得注意。
是的,自从我写了这个回复以来,已经添加了许多更好的方法。老问题有老答案!
s
siejkowski

从 iOS 8 开始,您可以轻松地在应用程序之间共享数据,只要它们位于公共应用程序组中即可。

Apple 文档在 Extensions 上下文中对其进行了最佳解释:https://developer.apple.com/library/prerelease/ios/documentation/General/Conceptual/ExtensibilityPG/ExtensionScenarios.html

基本上,您需要:

定义应用程序组 ID(在您的 Apple 开发人员计划的会员中心的证书、标识符和配置文件部分。启用应用程序组功能,为需要通信的每个应用程序指定上述应用程序组 ID(可以在 Xcode 中完成:Target -> Capabilities或在会员中心)。使用两个 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];

您放入 myDefaultssharedFolderURL 指向的文件夹中的任何内容都将对您的所有应用程序可见和可访问。

如果是文件夹,请以原子方式写入/读取,以确保不会出现死锁。


我完成了您的步骤并获得了共享网址。但是如何将图像放在该路径上。我附加我的图像名称并写入数据。然后我尝试检索但无法取回图像。
我已经成功地从 app1 中写入了所有图像,并使用 app 组从 app2 中检索了所有图像。谢谢 。 +1 :)。
我可以让第三方应用加入我的群组(通过选择),还是所有应用都必须来自同一个开发者帐户?
@DwarDoh 它必须来自同一个开发者帐户。
C
Community

可以在应用程序之间共享数据吗?是的!

使用 iOS 3.0 提供的 UIPasteBoard,提供文档 here。苹果文档说:

UIPasteboard 类使应用程序能够在应用程序内或使用系统范围或特定于应用程序的粘贴板与另一个应用程序共享数据。

也可以在钥匙串中的应用程序之间共享数据,尽管数据主要是密码等,可以存储任何可序列化的内容。 Here 是关于此的 Stack Overflow 问题。


伟大的!这看起来像是在应用程序之间共享数据的可行方式。
UIPasteboard 听起来像是共享小数据的好解决方案,例如复制粘贴字符串。是否有在应用程序之间共享文件的选项?
@AlikElzin-kilaka 是的,它也支持 NSData
C
Cœur

您可以使用自定义 URL 方案将数据从一个应用程序访问到另一个应用程序。按照下面提到的链接了解更多信息 -

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


这里的“访问数据”具有误导性。该链接指的是一篇文章,其中一些参数在 URL 本身中传递给应用程序。
M
MasterBeta

提到通过 UIPasteBoard 在应用程序之间共享数据仅适用于 iOS7 中同一应用程序组中的应用程序。正如苹果所说:

+[UIPasteboard pasteboardWithName:create:] 和 +[UIPasteboard pasteboardWithUniqueName] 现在唯一的给定名称仅允许同一应用程序组中的那些应用程序访问粘贴板。如果开发人员尝试使用已存在的名称创建粘贴板,并且它们不是同一应用程序套件的一部分,他们将获得自己独特的私有粘贴板。请注意,这不会影响系统提供的粘贴板、通用和查找。


Apple 所说的“同一应用程序组”是什么意思?
@MagicBulletDave 具有相同捆绑种子 ID 的应用程序。
UIPasteboard 类使应用程序能够在应用程序内以及与另一个应用程序共享数据。要与任何其他应用程序共享数据,您可以使用系统范围的粘贴板;要与与您的应用具有相同团队 ID 的其他应用共享数据,您可以使用特定于应用的粘贴板。
Q
QED

如果您不介意访问网络,您可以实现一个自定义 Web 服务来完成它,或者使用一些云服务。 iCloud 本身在这里用处不大;它只允许您在不同设备上的同一应用程序之间共享数据。您可以阅读有关 iCloud here 的信息。

在不使用网络的情况下,您可以利用“fast app switching”通过 URL 编码在应用之间传输有限数量的数据。我不知道可传输的实际数据量,但我敢肯定它会非常有限。

在这种情况下,JugsteR 和 baudot 的答案是最好的。


嗨,psoft,您能否简要介绍一下您在此处分两行解释的 iCloud 共享
我读到 iCloud ID 不必与应用程序的 Bundle ID 匹配,因此 iCloud 共享将是一种选择。
可以在标准 URL 内传输 64kB 的数据。它实际上运作良好。如果您没有太多数据,您可以加密/base64 以获得更好的安全性。
K
Kamil

您可以使用 https://github.com/burczyk/Camouflage 将 NSData 作为 .bmp 文件读取和写入 iOS 相机胶卷,并在应用程序之间共享 :)

全新解决方案!


创意...不错
d
dbrajkovic

不,您必须使用一些云解决方案。


据我所知,iCloud 用于将一台设备上的数据与其他设备同步。如果您知道任何在设备中的应用程序之间共享数据的方法,请分享。
dbarjkovic 你是对的,我们可以使用云解决方案在应用程序之间同步数据,因为用于 iCloud 的标识符与捆绑标识符不同,这是完全可能的。这是验证 stackoverflow.com/a/8882763/730807 的链接。为你的答案投票。
为什么这个答案被否决?这是正确的答案,但需要从文档中获取更多详细信息并给出一些示例