Giao tiếp và duy trì dữ liệu giữa các ứng dụng với Nhóm ứng dụng


85

iOS 8 đã tiết lộ một API mới vào ngày hôm qua liên quan đến Nhóm ứng dụng. Trước đây việc chia sẻ dữ liệu và giao tiếp giữa các ứng dụng khá lộn xộn và tôi tin rằng đó chính xác là những gì Nhóm ứng dụng muốn sửa.

Trong ứng dụng của mình, tôi đã bật Nhóm ứng dụng và thêm một nhóm mới nhưng tôi không thể tìm thấy bất kỳ tài liệu nào về cách sử dụng nó. Tài liệu và tài liệu tham khảo API chỉ nêu cách thêm nhóm.

Vậy App Groups thực sự dự định làm gì? Có tài liệu nào ở đâu đó về cách sử dụng nó không?

Câu trả lời:


81

Một lợi ích khác đối với Nhóm ứng dụng là khả năng chia sẻ NSUserDefaultscơ sở dữ liệu. Điều này cũng hoạt động đối với Tiện ích mở rộng ứng dụng (tiện ích con trong trung tâm thông báo, bàn phím tùy chỉnh, v.v.).

Khởi tạo NSUserDefaultsđối tượng của bạn như thế này trong tất cả các ứng dụng trong nhóm ứng dụng và chúng sẽ chia sẻ cơ sở dữ liệu:

Mục tiêu-C:

[[NSUserDefaults alloc] initWithSuiteName:@"<group identifier>"];

Nhanh:

NSUserDefaults(suiteName: "<group identifier>")

Hãy nhớ rằng mọi thứ từ [NSUserDefaults standardUserDefaults]cơ sở dữ liệu cho mỗi ứng dụng sẽ không được chuyển vào cơ sở dữ liệu này.

Các tài liệu đưa ra một ví dụ chính xác cũng (Tính đến Beta 3).

Và đừng quên đồng bộ hóa cơ sở dữ liệu:

[yourDefaults synchronize];

2
Chỉ hoạt động trên trình mô phỏng (XCode 6 beta 5, iOS 8 beta 5)
iOS Dev

8
LƯU Ý: Nếu bạn đang sử dụng tiện ích này với Tiện ích mở rộng iOS 8 (ví dụ: bàn phím), bạn cần đảm bảo tiện ích mở rộng của mình có RequestOpenAccess = YES trong tệp Info.plist của nó.
Kiran Panesar

1
Tôi đã làm RequestOpenAccess = YES và vẫn làm theo hướng dẫn, nó vẫn không hoạt động với tôi trên Thiết bị và hoạt động tốt trên Trình mô phỏng, bất kỳ thứ gì cụ thể cho thiết bị?
MAC

Cùng một vấn đề với tôi, tôi đã tích hợp tiện ích mở rộng chia sẻ trong ứng dụng của mình, nó hoạt động trên trình mô phỏng, nhưng không hoạt động trên thiết bị thực, tôi đã thêm RequestOpenAccess = YES nhưng nó không hoạt động, câu hỏi của tôi là stackoverflow.com/questions/30489894/ …
Ravi Ojha

3
@MikeRichards không chắc, nhưng nếu tôi nhớ không nhầm thì các nhóm ứng dụng có tiền tố là id nhóm
Santa Claus

74

Chia sẻ dữ liệu NSUserDefaults giữa nhiều ứng dụng

Để có mặc định được chia sẻ giữa ứng dụng và tiện ích mở rộng hoặc giữa 2 ứng dụng, bạn phải thêm Nhóm ứng dụng trong cài đặt của mình bằng các bước sau:

  1. Trong Project Navigator, hãy nhấp vào tệp * .xcodeproj (phải ở trên cùng).
  2. Ở bên phải của Project Navigator, tìm Dự án và Mục tiêu. Trong mục tiêu, hãy nhấp vào mục tiêu chính của bạn (phải là điều đầu tiên trong Mục tiêu).
  3. Ở trên cùng, hãy nhấp vào tab Khả năng.
  4. Trong phần Nhóm ứng dụng, nhấp vào công tắc bên phải để BẬT Nhóm ứng dụng.
  5. Nhấp vào nút + và thêm Nhóm ứng dụng có tên group.com.company.myApp .
  6. Chuyển đến cùng một vị trí trong các ứng dụng khác của bạn và nhóm này bây giờ sẽ có sẵn để chọn. Bật nhóm này cho từng ứng dụng sẽ sử dụng dữ liệu được chia sẻ này.

Lưu ý: Nếu bạn truy cập Cổng thông tin dành cho nhà phát triển Apple (trang web của Apple hiển thị tất cả Chứng chỉ, Số nhận dạng, Thiết bị và Hồ sơ cấp phép của bạn) và chuyển đến Số nhận dạng> Nhóm ứng dụng, bạn sẽ thấy Nhóm ứng dụng mới này.

Để lưu trữ dữ liệu:

var userDefaults = NSUserDefaults(suiteName: "group.com.company.myApp")!
userDefaults.setObject("user12345", forKey: "userId")
userDefaults.synchronize()

Để truy xuất dữ liệu:

var userDefaults = NSUserDefaults(suiteName: "group.com.company.myApp")
if let testUserId = userDefaults?.objectForKey("userId") as? String {
  print("User Id: \(testUserId)")
}

2
Cảm ơn! Phải mất một chút tìm kiếm thông qua tài liệu để tìm ra cách thực hiện việc này và tôi nghĩ những người khác có thể đánh giá cao các bước tôi đã thực hiện.
TenaciousJay

Cảm ơn vì mô tả chi tiết ...! chúng tôi có cần tạo bất kỳ chứng chỉ nào từ Cổng nhà phát triển Apple (trang web của Apple hiển thị tất cả Chứng chỉ, Số nhận dạng, Thiết bị và Hồ sơ cấp phép của bạn) để kích hoạt nhóm này không? giống như Thông báo đẩy.?
Arbaz Shaikh

Khi bạn thực hiện bước 5, nó sẽ thêm Nhóm ứng dụng vào Cổng nhà phát triển của Apple, bạn không cần phải truy cập trực tiếp vào Cổng nhà phát triển để thêm nó. Sau khi thực hiện bước 5, bạn có thể truy cập cổng thông tin và thấy rằng lẽ ra nó phải tạo nó cho bạn.
TenaciousJay

@TenaciousJay Câu trả lời tuyệt vời. Chỉ muốn thêm Nếu bạn muốn khởi chạy ứng dụng từ các ứng dụng func (ứng dụng: UIApplication, openURL url: NSURL, tùy chọn: [String: AnyObject]) -> Bool
Taimur Ajmal

câu trả lời chính xác. cảm ơn @TenaciousJay. Tôi đang cố gắng truy xuất một biến và giá trị của nó từ AppB vào AppA, tôi sẽ làm như thế nào? Ví dụ: nếu "riderCanceltRequest = true" trong AppB, làm cách nào để lấy thông tin này trong AppA?
LizG

37

Các nhóm ứng dụng, theo cách hiểu của tôi về tài liệu hiện có, chủ yếu được nhắm mục tiêu cho các tiện ích mở rộng, cụ thể hơn là cho các tiện ích con. Widget là gói ứng dụng của riêng chúng cùng tồn tại với ứng dụng của bạn. Vì chúng là một ứng dụng riêng biệt và do đó có hộp cát riêng, bạn sẽ cần sử dụng Nhóm ứng dụng để chia sẻ tệp.

Sau một số thao tác gửi email tiêu đề, tôi nghĩ rằng tôi thấy API cần thiết, nhưng thực sự đã được đưa vào như một phần của iOS 7.

NSFileManagercó một phương pháp trên đó containerURLForSecurityApplicationGroupIdentifier:để bạn có thể nhập mã nhận dạng mà bạn đã tạo khi bật Nhóm ứng dụng cho ứng dụng của mình:

NSURL *containerURL = [[NSFileManager defaultManager] 
           containerURLForSecurityApplicationGroupIdentifier:@"group.com.company.app"];

Cảm ơn, tôi tin rằng bạn nói đúng về khả năng mở rộng. Tôi hơi nghi ngờ về phương pháp iOS 7 này, nó có vẻ khá tĩnh đối với tôi, iOS 8 đã giới thiệu các tương tác và giao tiếp thực giữa các ứng dụng.
streem

@Justafinger Phương pháp iOS 7 này chỉ để tạo URL để ghi và đọc từ dữ liệu giữa các ứng dụng được chia sẻ. Phương pháp cụ thể này chỉ thực sự hữu ích (theo những gì tôi thấy cho đến nay) cho các widget, chứ không phải các tiện ích mở rộng khác.
Wayne Hartman

Chà, tôi tin rằng Apple muốn làm điều này dễ dàng hơn trong iOS 8 mà không cần phải tạo vùng chứa theo chương trình và chia sẻ các tệp tùy chỉnh. Tài liệu nói rằng bạn có thể chia sẻ dữ liệu bằng cách sử dụng NSUserDefault. Tôi đoán tôi đang thiếu một cái gì đó, bởi vì điều đó không phù hợp với tôi.
streem

@Justafinger Tôi cũng không thể NSUserDefaultsđi làm. Tôi phấn đấu đến lỗi Beta 1.
Wayne Hartman

@WayneHartman Có một giải pháp cho NSUserDefaultscơ sở dữ liệu. Hãy xem câu trả lời của tôi.
Santa Claus

6

Một cái bẫy quan trọng mà tôi đã mắc phải hôm nay là:

Trong nhiều dự án, tôi đã thấy một mục tiêu ứng dụng duy nhất và với các số nhận dạng gói khác nhau được đặt cho từng cấu hình của mục tiêu đó. Ở đây mọi thứ trở nên lộn xộn. Mục đích của các nhà phát triển là tạo một ứng dụng gỡ lỗi cho cấu hình gỡ lỗi và một ứng dụng sản xuất cho mục tiêu phát hành.

Nếu bạn làm như vậy, cả hai ứng dụng sẽ chia sẻ cùng một NSUserDefaults khi chúng được thiết lập như vậy

var userDefaults = NSUserDefaults(suiteName: "group.com.company.myApp")
userDefaults!.setObject("user12345", forKey: "userId")
userDefaults!.synchronize()

Điều này gây ra vấn đề ở nhiều nơi:

  1. Hãy tưởng tượng bạn đặt CÓ cho một khóa khi màn hình giới thiệu ứng dụng đặc biệt được hiển thị cho người dùng. Ứng dụng khác bây giờ cũng sẽ đọc CÓ và không hiển thị phần giới thiệu.
  2. Có một số ứng dụng cũng lưu trữ mã thông báo oAuth ở chế độ mặc định của người dùng. Dù sao thì ... Tùy thuộc vào việc triển khai, ứng dụng sẽ nhận ra rằng có một mã thông báo và bắt đầu truy xuất dữ liệu bằng cách sử dụng mã thông báo sai. Khả năng cao là điều này sẽ không thành công với các lỗi lạ.

Giải pháp cho vấn đề này nói chung là đặt tiền tố cho các khóa mặc định với cấu hình hiện tại được xây dựng. Bạn có thể dễ dàng phát hiện cấu hình trong thời gian chạy bằng cách đặt các số nhận dạng gói khác nhau cho cấu hình của mình. Sau đó, chỉ cần đọc số nhận dạng gói từ NSBundle.mainBundle(). Nếu bạn có cùng một số nhận dạng gói, bạn cần đặt các macro tiền xử lý khác nhau như

#ifdef DEBUG
  NSString* configuration = @"debug";
#elif RELEASE
  NSString* configuration = @"release";
#endif

Trong Swift, nó sẽ gần như giống nhau:

#if DEBUG
  let configuration = "debug"
#elseif RELEASE
  let configuration = "release"
#endif

8
Sự cố của bạn tồn tại do bạn kết hợp tất cả dữ liệu của mình trong một UserDefaults được chia sẻ. Bạn nên sử dụng NSUserDefaults.standardUserDefaults()cho dữ liệu không nên chia sẻ.
Daniel

2

Để lưu trữ

let shared: NSUserDefaults = NSUserDefaults(suiteName: "group.abcapp")!
shared.setObject("abc.png", forKey: "favEmoji")
shared.synchronize()
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.