Swift:在两个设备之间发送自定义数据(不在同一网络上)

威尔

我是 ios 开发的新手。

我已经构建了将数据保存在核心数据中的应用程序。我想做的是与我的 Ipad 或我的孩子 Iphone 共享这些数据。

设备不在同一网络上或彼此关闭,因此共享过程将通过电子邮件或 Imessage。

该应用程序将安装在所有设备上,以便发送/接收数据。

我想确定唯一的方法是使用 UIActivityViewController。

我还没有开始编码部分(分享部分),我还在做一些研究和一些好的建议。

谢谢你的帮忙

// 完整代码

经过大量搜索后,这里是我的代码,我不知道是否有更好的方法来做到这一点,但这是我解决的方法:

1 - 创建一个 Json 字符串

      let savedData = ["Something": 1]
      let jsonObject: [String: Any] = [
        "type_id": 1,
        "model_id": true,
        "Ok": [
            "startDate": "10-04-2015 12:45",
            "endDate": "10-04-2015 16:00"
        ],
        "custom": savedData
    ]

2 - 保存为文件

     let objectsToShare = [jsonObject as AnyObject]
   let data: Data? = try? JSONSerialization.data(withJSONObject: objectsToShare, options: .prettyPrinted)
     let filePath = NSTemporaryDirectory() + "/" + NSUUID().uuidString + ".kis"

    do
   {
    try data?.write(to: URL(fileURLWithPath: filePath))

    }
    catch {

    }
    print (filePath)
    // create activity view controller
    let activityItem:NSURL = NSURL(fileURLWithPath:filePath)
    let activityViewController = UIActivityViewController(activityItems: [activityItem], applicationActivities: nil)
    self.present(activityViewController, animated: true, completion: nil)

3 - 更新 info.plist

 <key>CFBundleDocumentTypes</key>
  <array>
    <dict>
        <key>LSItemContentTypes</key>
        <array>
            <string>XXXSharingData.kis</string>
        </array>
        <key>CFBundleTypeRole</key>
        <string>Viewer</string>
        <key>CFBundleTypeName</key>
        <string>kis file</string>
        <key>LSHandlerRank</key>
        <string>Owner</string>
    </dict>
</array>
<key>UTExportedTypeDeclarations</key>
<array>
    <dict>
        <key>UTTypeConformsTo</key>
        <array>
            <string>public.data</string>
        </array>
        <key>UTTypeIdentifier</key>
        <string>XXXSharingData.kis</string>
        <key>UTTypeTagSpecification</key>
        <dict>
            <key>public.mime-type</key>
            <string>application/pry</string>
            <key>public.filename-extension</key>
            <string>kis</string>
        </dict>
    </dict>
</array>

最后,当通过电子邮件将文件作为附件发送/接收并在我的应用程序中打开时:打开方法 appdelegate,我能够看到 Json 字符串

func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
    do
    {
        let dictionary =  try NSString(contentsOf: url, encoding: String.Encoding.utf8.rawValue)
        print (dictionary)
    }
    catch {

    }
    return true
}
马蒂奇奥布拉克

总的来说,总体上有 2 个原则。您要么不想发送数据差异,要么不想发送整个数据本身。

首先,我只会按需发送整个数据包,因为差异意味着目标设备需要首先报告它所处的状态。

因此,要传输整个核心数据,我想应该可以简单地压缩存储数据库的整个文件夹,将 zip 扩展名更改为某个自定义名称,然后简单地发送此文件。然后把另一边的这个文件解压到对应的位置。

但这并不是很好,因为它不能移植到任何其他系统(Android、远程存储...)并且会有版本控制问题:如果更新数据模型,那么在导入旧数据库时,新应用程序将崩溃。

所以我会说发送任何标准数据块都是最好的:只需将所有核心数据实体转换为字典,然后将这些数据序列化为 JSON。因此像这样:

var JSONDictionary: [String: Any] = [String: Any]()
JSONDictionary["users"] = User.fetchAll().map { $0.toDictionary() }
JSONDictionary["tags"] = Tag.fetchAll().map { $0.toDictionary() }
JSONDictionary["notifications"] = Notification.fetchAll().map { $0.toDictionary() }
let data: Data? = try? JSONSerialization.data(withJSONObject: JSONDictionary, options: .prettyPrinted)
let filePath = NSTemporaryDirectory() + "/" + NSUUID().uuidString + ".myApplicationFileExtension"
Data().write(to: URL(fileURLWithPath: filePath))

因此,此时您的文件很容易共享,并且可以在另一侧反转。然后您可以选择合并数据,覆盖它...

编辑:从评论和更新的问题中添加更多描述

  1. 我不确定你的数据结构是什么,但似乎我期望的是:

        class MyObject {
            enum ObjectType {
                case a,b,c
                var id: String {
                    switch self {
                    case .a: return "1"
                    case .b: return "2"
                    case .c: return "3"
                    }
                }
                static let supportedValues: [ObjectType] = [.a, .b, .c]
            }
    
            var savedData: [String: Any]?
            var type: ObjectType = .a
            var isModel: Bool = false
            var startDate: Date?
            var endDate: Date?
    
            func toDictionary() -> [String: Any] {
                var dictionary: [String: Any] = [String: Any]()
                dictionary["custom"] = savedData
                dictionary["type_id"] = type.id
                dictionary["model_id"] = isModel
                dictionary["startDate"] = startDate?.timeIntervalSince1970
                dictionary["endDate"] = endDate?.timeIntervalSince1970
                return dictionary
            }
    
            func loadWithDescriptor(_ descriptor: Any?) {
                if let dictionary = descriptor as? [String: Any] {
                    savedData = dictionary["custom"] as? [String: Any]
                    type = ObjectType.supportedValues.first(where: { $0.id == dictionary["type_id"] as? String }) ?? .a
                    isModel = dictionary["model_id"] as? Bool ?? false
                    startDate = {
                        guard let interval = dictionary["startDate"] as? TimeInterval else {
                            return nil
                        }
                        return Date(timeIntervalSince1970: interval)
                    }()
                    endDate = {
                        guard let interval = dictionary["endDate"] as? TimeInterval else {
                            return nil
                        }
                        return Date(timeIntervalSince1970: interval)
                    }()
                }
            }
        }
    

因此,现在这将使您能够在字典(不是 JSON)之间进行转换。

  1. 活动控制器不是问题,保存到文件似乎也不是什么大问题。我不确定一些属性,但它应该看起来像这样:

        func saveToTemporaryFile(myConcreteObjects: [MyObject]) -> String {
            let dictionaryObjects: [[String: Any]] = myConcreteObjects.map { $0.toDictionary() }
    
            let path = NSTemporaryDirectory() + "/" + NSUUID().uuidString + ".kis"
    
            let data: Data? = try? JSONSerialization.data(withJSONObject: dictionaryObjects, options: .prettyPrinted)
            try? data?.write(to: URL(fileURLWithPath: path))
    
            return path
        }
    

如果碰巧你有不同的对象,那么这个方法应该接受Any应该构造为的对象:

var myDataObject: [String: Any] = [String: Any]()
myDataObject["myObjects"] = myConcreteObjects.map { $0.toDictionary() }
...
  1. 要从 URL 加载您的 JSON,您只需要构建您的数据。既然你得到了 URL,就不要理会字符串:

    func loadItemsFrom(url: URL) -> [MyObject]? {
        guard let data = try? Data(contentsOf: url) else {
            // Error, could not load data
            return nil
        }
        guard let array = (try? JSONSerialization.jsonObject(with: data, options: .allowFragments)) as? [Any] else {
            // Error, could not convert to JSON or invalid type
            return nil
        }
    
        return array.map { descriptor in
            let newItem = MyObject()
            newItem.loadWithDescriptor(descriptor)
            return newItem
        }
    }
    

这个从 URL 获取数据的构造函数非常强大。如果您可以访问互联网/网络,它甚至可以与远程服务器一起使用。因此,在这些情况下,请确保您在单独的线程上执行此操作,否则您的 UI 可能会被阻止,直到收到数据。

我希望这可以清除一些事情......

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

试图了解同一网络上两个不同子网之间的交互

来自分类Dev

具有相同MAC地址的两个设备可以位于同一网络上吗?

来自分类Dev

同一网络上的两个网关

来自分类Dev

从不在同一网络上的设备连接Flask Web服务

来自分类Dev

不在同一网络中的两台服务器之间的scp

来自分类Dev

如何使两个接口在同一网络中使用同一网关?

来自分类Dev

在Sencha Touch中同一网络上的设备之间传输消息

来自分类Dev

无法在同一网络上的2个SQL服务器之间传输数据

来自分类Dev

在Unity中同一网络上的2个iOS手机之间传输小数据

来自分类Dev

在同一网络中运行两个DHCP服务器

来自分类Dev

同一网络适配器的两个IP

来自分类Dev

同一网络上同一台PC上的两个IPv4适配器有效吗?

来自分类Dev

在Android设备和PC(同一网络)之间使用套接字

来自分类Dev

在Android设备和PC(同一网络)之间使用套接字

来自分类Dev

当机器通过两个接口连接到同一网络时,如何分配IP?

来自分类Dev

从同一网络上的其他设备连接到Flask Server

来自分类Dev

同一网络上设备的磁盘空间

来自分类Dev

无法解析同一网络上设备的IP地址

来自分类Dev

同一网络上的无线设备无法相互访问

来自分类Dev

同一网络中的nic之间的数据包转发(wifi / eth)

来自分类Dev

在同一网络上使用2个NIC进行策略路由似乎无济于事

来自分类Dev

如果为同一网络配置了两个网卡,为什么两个网卡不能工作,我可以解决这个问题吗?

来自分类Dev

将数据包从一台计算机发送到不在同一网络上的另一台计算机

来自分类Dev

如何从同一网络上的另一台设备连接到localhost:8888?

来自分类Dev

是否需要端口转发以在同一网络上的两台计算机之间进行通信?

来自分类Dev

当主机需要将数据包发送到同一网络中的另一主机时

来自分类Dev

在同一网络上的Windows和Ubuntu之间共享文件时,我有哪些选择?

来自分类Dev

在同一网络上的Windows和Ubuntu之间共享文件时,我有哪些选择?

来自分类Dev

无法对同一网络VirtualBox上的两台计算机执行ping操作

Related 相关文章

  1. 1

    试图了解同一网络上两个不同子网之间的交互

  2. 2

    具有相同MAC地址的两个设备可以位于同一网络上吗?

  3. 3

    同一网络上的两个网关

  4. 4

    从不在同一网络上的设备连接Flask Web服务

  5. 5

    不在同一网络中的两台服务器之间的scp

  6. 6

    如何使两个接口在同一网络中使用同一网关?

  7. 7

    在Sencha Touch中同一网络上的设备之间传输消息

  8. 8

    无法在同一网络上的2个SQL服务器之间传输数据

  9. 9

    在Unity中同一网络上的2个iOS手机之间传输小数据

  10. 10

    在同一网络中运行两个DHCP服务器

  11. 11

    同一网络适配器的两个IP

  12. 12

    同一网络上同一台PC上的两个IPv4适配器有效吗?

  13. 13

    在Android设备和PC(同一网络)之间使用套接字

  14. 14

    在Android设备和PC(同一网络)之间使用套接字

  15. 15

    当机器通过两个接口连接到同一网络时,如何分配IP?

  16. 16

    从同一网络上的其他设备连接到Flask Server

  17. 17

    同一网络上设备的磁盘空间

  18. 18

    无法解析同一网络上设备的IP地址

  19. 19

    同一网络上的无线设备无法相互访问

  20. 20

    同一网络中的nic之间的数据包转发(wifi / eth)

  21. 21

    在同一网络上使用2个NIC进行策略路由似乎无济于事

  22. 22

    如果为同一网络配置了两个网卡,为什么两个网卡不能工作,我可以解决这个问题吗?

  23. 23

    将数据包从一台计算机发送到不在同一网络上的另一台计算机

  24. 24

    如何从同一网络上的另一台设备连接到localhost:8888?

  25. 25

    是否需要端口转发以在同一网络上的两台计算机之间进行通信?

  26. 26

    当主机需要将数据包发送到同一网络中的另一主机时

  27. 27

    在同一网络上的Windows和Ubuntu之间共享文件时,我有哪些选择?

  28. 28

    在同一网络上的Windows和Ubuntu之间共享文件时,我有哪些选择?

  29. 29

    无法对同一网络VirtualBox上的两台计算机执行ping操作

热门标签

归档