Một số nền
Tôi đang làm việc trên ứng dụng iOS nơi chúng tôi muốn trạng thái của ứng dụng được giữ nguyên.
Trước khi ứng dụng này hết, iOS 7 có thể đã được phát hành hoặc sắp được phát hành và phần lớn dường như đã chuyển khỏi iOS 5. Do đó chúng tôi đã quyết định phát triển iOS 6 trở đi.Lưu thủ công trạng thái bảo quản trong iOS 6 trở đi
Trong iOS 6, có một số chức năng thực sự tốt để giữ trạng thái. Chỉ cần cung cấp cho tất cả các quan điểm trong các ID duy kịch bản và thực hiện hai chức năng trong "appdelegate":
- (BOOL)application:(UIApplication*)application shouldSaveApplicationState:(NSCoder*)coder;
- (BOOL)application:(UIApplication*)application shouldRestoreApplicationState:(NSCoder*)coder;
iOS sẽ sau đó "Automagically" lưu giữ lịch sử chuyển hướng của ứng dụng. Các phương pháp:
- (void)encodeRestorableStateWithCoder:(NSCoder*)coder;
- (void)decodeRestorableStateWithCoder:(NSCoder*)coder;
sau đó có thể được sử dụng để lưu trữ và truy xuất dữ liệu.
Không có vấn đề ở đó nó hoạt động mà không có vấn đề. Tuy nhiên, các phương pháp lưu trạng thái chỉ được kích hoạt khi ứng dụng đã nhập vào nền.
Giả sử chúng ta có một NavigationController với bốn ViewControllers: A, B, C và D. Người dùng điều hướng từ A đến B, trong B anh ta chuyển sang Safari để google một cái gì đó. Trạng thái ứng dụng được lưu trong B. Người dùng sau đó chuyển về ứng dụng và điều hướng đến C và sau đó đến D. Trong D, ứng dụng không may gặp phải một ngoại lệ và đi xuống. Khi người dùng khởi động lại ứng dụng, iOS sẽ cố khôi phục trạng thái đã lưu. Tuy nhiên, khi ứng dụng khởi chạy, nó không bắt đầu ngay từ đầu, không phải là nơi người dùng rời khỏi nó (D) và thậm chí không phải khung nhìn trước đó (C) mà ở B.
Một giải pháp có thể
Kịch bản trên có thể tránh được nếu ứng dụng đã lưu trạng thái của nó ở mọi chế độ xem mới. Tuy nhiên không có (theo như tôi biết) bất kỳ phương pháp nào để kích hoạt quá trình bảo tồn của tiểu bang. Tôi đã kiểm tra các cuộc gọi stack trong khi gỡ lỗi và phát hiện ra rằng iOS gọi phương thức sau đây trên đối tượng UIApplication trong iOS 6:
_saveApplicationPreservationState:
và phương pháp sau đây trong iOS 7:
_saveApplicationPreservationState:viewController:sessionIdentifier:beginHandler:completionHandler:
cũng
Có có vẻ là một phương pháp khác gọi một trong các phương pháp trên tùy thuộc vào phiên bản iOS:
_saveApplicationPreservationStateIfSupported
Bằng cách gọi phương thức này như sau:
if ([[UIApplication sharedApplication] respondsToSelector:@selector(_saveApplicationPreservationStateIfSupported)])
[[UIApplication sharedApplication] performSelector:@selector(_saveApplicationPreservationStateIfSupported)];
Tôi có thể thấy rằng các phương pháp dự kiến được gọi.
Câu hỏi thực tế
Nếu tôi đi với giải pháp trên có thể khiến ứng dụng của tôi bị từ chối khỏi App Store? Tôi có nghĩa là về mặt kỹ thuật nó không phải là một phương pháp riêng tư, nó chỉ là không tiếp xúc. Bằng cách gói các cuộc gọi trong "respondsToSelector" ứng dụng sẽ không sụp đổ nếu các API được thay đổi, nó sẽ không lưu trạng thái như thường lệ. Nhưng nếu nó có thể khiến ứng dụng bị từ chối thì đó không phải là một lựa chọn. Hoặc có cách nào khác để gọi thủ công quá trình bảo quản của tiểu bang khác với quy trình được mô tả ở trên không? Tôi sẽ rất vui khi có thể sử dụng chức năng tích hợp sẵn hơn là xây dựng giải pháp tùy chỉnh giúp tiết kiệm trạng thái thành NSUserDefaults
.
Thực tế là các phương pháp đó được đặt tên với dấu gạch dưới hàng đầu nên hoạt động như một gợi ý ** mạnh mẽ cho bạn rằng chúng không phải là một phần của bất kỳ API công khai nào và do đó sử dụng chúng có thể dẫn đến từ chối App Store. –
+1, đó là một câu hỏi hay và tôi cũng muốn biết câu trả lời. Tôi nghĩ rằng John là đúng tuy nhiên về những phương pháp, khá sơ sài. – John
Tôi cũng rất quan tâm đến điều này. Dự đoán tiếp theo của chúng tôi là chúng ta nên triển khai tất cả các phương pháp để bảo toàn trạng thái khởi chạy/thoát ứng dụng (cách tiếp cận tích hợp thông thường), nhưng cũng tạo ra máy móc riêng của chúng ta để bảo tồn/khôi phục trạng thái trong các thay đổi trạng thái thời gian chạy - hy vọng sử dụng lại càng nhiều mã triển khai khác càng tốt. Tôi đang nghĩ rằng chúng tôi có thể sử dụng lại các phương thức mã hóa/giải mã của ID và các phương thức giải mã/mã hóa tương tự với NSUserDefaults. –