-
Notifications
You must be signed in to change notification settings - Fork 58
feat(springboard): add get_icon_state and set_icon_state methods with iOS 18+ support #63
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
9fc41c5
36935f1
a1036a3
2e740e9
8fbd8a4
b6a0256
d926817
6408604
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -3,7 +3,7 @@ | |||||||||||||||||||||
| //! Provides functionality for interacting with the SpringBoard services on iOS devices, | ||||||||||||||||||||||
| //! which manages home screen and app icon related operations. | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| use crate::{Idevice, IdeviceError, IdeviceService, obf}; | ||||||||||||||||||||||
| use crate::{obf, Idevice, IdeviceError, IdeviceService}; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| /// Client for interacting with the iOS SpringBoard services | ||||||||||||||||||||||
| /// | ||||||||||||||||||||||
|
|
@@ -70,4 +70,52 @@ impl SpringBoardServicesClient { | |||||||||||||||||||||
| _ => Err(IdeviceError::UnexpectedResponse), | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| /// Retrieves the current icon state from the device | ||||||||||||||||||||||
| /// | ||||||||||||||||||||||
| /// The icon state contains the layout and organization of all apps on the home screen, | ||||||||||||||||||||||
| /// including folder structures and icon positions. This is a read-only operation. | ||||||||||||||||||||||
| /// | ||||||||||||||||||||||
| /// # Arguments | ||||||||||||||||||||||
| /// * `format_version` - Optional format version string for the icon state format | ||||||||||||||||||||||
| /// | ||||||||||||||||||||||
| /// # Returns | ||||||||||||||||||||||
| /// A plist Value containing the complete icon state structure | ||||||||||||||||||||||
| /// | ||||||||||||||||||||||
| /// # Errors | ||||||||||||||||||||||
| /// Returns `IdeviceError` if: | ||||||||||||||||||||||
| /// - Communication fails | ||||||||||||||||||||||
| /// - The response is malformed | ||||||||||||||||||||||
| /// | ||||||||||||||||||||||
| /// # Example | ||||||||||||||||||||||
| /// ```rust | ||||||||||||||||||||||
| /// use idevice::services::springboardservices::SpringBoardServicesClient; | ||||||||||||||||||||||
| /// | ||||||||||||||||||||||
| /// let mut client = SpringBoardServicesClient::connect(&provider).await?; | ||||||||||||||||||||||
| /// let icon_state = client.get_icon_state(None).await?; | ||||||||||||||||||||||
| /// println!("Icon state: {:?}", icon_state); | ||||||||||||||||||||||
| /// ``` | ||||||||||||||||||||||
| /// | ||||||||||||||||||||||
| /// # Notes | ||||||||||||||||||||||
| /// This method successfully reads the home screen layout on all iOS versions. | ||||||||||||||||||||||
| /// Note that modifying and setting icon state (setIconState) does not work | ||||||||||||||||||||||
| /// on iOS 18+ due to Apple's security restrictions. See issue #62 for details. | ||||||||||||||||||||||
| pub async fn get_icon_state( | ||||||||||||||||||||||
| &mut self, | ||||||||||||||||||||||
| format_version: Option<String>, | ||||||||||||||||||||||
| ) -> Result<plist::Value, IdeviceError> { | ||||||||||||||||||||||
| let mut req = crate::plist!({ | ||||||||||||||||||||||
| "command": "getIconState", | ||||||||||||||||||||||
fulln marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||
| }); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| if let Some(version) = format_version { | ||||||||||||||||||||||
| if let Some(dict) = req.as_dictionary_mut() { | ||||||||||||||||||||||
| dict.insert("formatVersion".to_string(), plist::Value::String(version)); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| self.idevice.send_plist(req).await?; | ||||||||||||||||||||||
| let res = self.idevice.read_plist_value().await?; | ||||||||||||||||||||||
|
||||||||||||||||||||||
| let res = self.idevice.read_plist_value().await?; | |
| let res = self.idevice.read_plist_value().await?; | |
| // Some devices may return an error dictionary instead of icon state. | |
| // Detect this and surface it as an UnexpectedResponse, similar to get_icon_pngdata. | |
| if let plist::Value::Dictionary(ref dict) = res { | |
| if dict.contains_key("error") || dict.contains_key("Error") { | |
| return Err(IdeviceError::UnexpectedResponse); | |
| } | |
| } |
Uh oh!
There was an error while loading. Please reload this page.