Skip to main content

storekit/
app_store.rs

1use core::ptr;
2
3use crate::error::StoreKitError;
4use crate::ffi;
5use crate::private::{error_from_status, take_string};
6
7#[derive(Debug, Clone, PartialEq, Eq)]
8pub enum AppStoreEnvironment {
9    Production,
10    Sandbox,
11    Xcode,
12    Unknown(String),
13}
14
15impl AppStoreEnvironment {
16    pub fn as_str(&self) -> &str {
17        match self {
18            Self::Production => "production",
19            Self::Sandbox => "sandbox",
20            Self::Xcode => "xcode",
21            Self::Unknown(value) => value.as_str(),
22        }
23    }
24
25    pub(crate) fn from_raw(raw: String) -> Self {
26        match raw.as_str() {
27            "production" => Self::Production,
28            "sandbox" => Self::Sandbox,
29            "xcode" => Self::Xcode,
30            _ => Self::Unknown(raw),
31        }
32    }
33}
34
35#[derive(Debug, Clone, PartialEq, Eq)]
36pub enum AppStorePlatform {
37    IOS,
38    MacOS,
39    TvOS,
40    VisionOS,
41    Unknown(String),
42}
43
44impl AppStorePlatform {
45    pub fn as_str(&self) -> &str {
46        match self {
47            Self::IOS => "iOS",
48            Self::MacOS => "macOS",
49            Self::TvOS => "tvOS",
50            Self::VisionOS => "visionOS",
51            Self::Unknown(value) => value.as_str(),
52        }
53    }
54
55    pub(crate) fn from_raw(raw: String) -> Self {
56        match raw.as_str() {
57            "iOS" => Self::IOS,
58            "macOS" => Self::MacOS,
59            "tvOS" => Self::TvOS,
60            "visionOS" => Self::VisionOS,
61            _ => Self::Unknown(raw),
62        }
63    }
64}
65
66/// Helpers backed by `StoreKit.AppStore`.
67#[derive(Debug, Clone, Copy, Default)]
68pub struct AppStore;
69
70impl AppStore {
71    pub fn can_make_payments() -> Result<bool, StoreKitError> {
72        let mut raw_value = 0;
73        let mut error_message = ptr::null_mut();
74        let status =
75            unsafe { ffi::sk_app_store_can_make_payments(&mut raw_value, &mut error_message) };
76        if status == ffi::status::OK {
77            Ok(raw_value != 0)
78        } else {
79            Err(unsafe { error_from_status(status, error_message) })
80        }
81    }
82
83    pub fn device_verification_id() -> Result<Option<String>, StoreKitError> {
84        let mut uuid_ptr = ptr::null_mut();
85        let mut error_message = ptr::null_mut();
86        let status =
87            unsafe { ffi::sk_app_store_device_verification_id(&mut uuid_ptr, &mut error_message) };
88        if status == ffi::status::OK {
89            Ok(unsafe { take_string(uuid_ptr) })
90        } else {
91            Err(unsafe { error_from_status(status, error_message) })
92        }
93    }
94
95    pub fn sync() -> Result<(), StoreKitError> {
96        let mut error_message = ptr::null_mut();
97        let status = unsafe { ffi::sk_app_store_sync(&mut error_message) };
98        if status == ffi::status::OK {
99            Ok(())
100        } else {
101            Err(unsafe { error_from_status(status, error_message) })
102        }
103    }
104
105    pub fn show_manage_subscriptions() -> Result<(), StoreKitError> {
106        let mut error_message = ptr::null_mut();
107        let status = unsafe { ffi::sk_app_store_show_manage_subscriptions(&mut error_message) };
108        if status == ffi::status::OK {
109            Ok(())
110        } else {
111            Err(unsafe { error_from_status(status, error_message) })
112        }
113    }
114
115    pub fn request_review() -> Result<(), StoreKitError> {
116        let mut error_message = ptr::null_mut();
117        let status = unsafe { ffi::sk_app_store_request_review(&mut error_message) };
118        if status == ffi::status::OK {
119            Ok(())
120        } else {
121            Err(unsafe { error_from_status(status, error_message) })
122        }
123    }
124
125    pub fn present_offer_code_redeem_sheet() -> Result<(), StoreKitError> {
126        let mut error_message = ptr::null_mut();
127        let status =
128            unsafe { ffi::sk_app_store_present_offer_code_redeem_sheet(&mut error_message) };
129        if status == ffi::status::OK {
130            Ok(())
131        } else {
132            Err(unsafe { error_from_status(status, error_message) })
133        }
134    }
135}