General Concepts
Core concepts shared across Shiply SDKs on all platforms. Understanding these concepts before integrating any platform helps avoid cross-platform confusion.
Credentials and Identifiers
| Concept | Meaning | How to Obtain | Field Names by Platform |
|---|---|---|---|
| appId | Unique application identifier | Shiply Web Console → Project Settings → App Information | iOS/Android appId; Harmony appId |
| appKey | Application authentication key | Same as above | appKey |
| guid / userId | User identifier for gray release matching by number package/rules | Business-defined (e.g., uin/openid) | iOS guid; Android/Harmony userId |
| qimei / deviceId | Device identifier for reporting and device-dimension rules | Business-injected (privacy compliance; SDK does not actively obtain) | iOS qimei; Android/Harmony deviceId |
Privacy Compliance: Privacy information such as system version, device model, and device identifiers is not actively obtained by the SDK and must be injected by the business. This is a common convention across all platforms.
Environment Identifiers
| Concept | Meaning | Field Names by Platform |
|---|---|---|
| envId | Environment numeric ID | iOS envId (default RDeliveryReleaseEnvId for production; also RDEnvironmentIotRelease = 3 for IoT release environment) |
| logicEnvironment | Logical environment string | Harmony logicEnvironment ("" = production, "1" = test, others = custom environment numeric ID) |
| environment | Resource SDK environment | Windows ResHub environment (0 = Release, 1 = Test, 2 = Pre-release) |
iOS configuration uses envId; Harmony uses logicEnvironment (string). Do not mix them. Resource SDK's environment and configuration's logicEnvironment are separate fields, each independent.
Update Strategies
Configuration SDK combines update strategies through bit masks; resource SDK is similar.
| Strategy | iOS Enum | Android Enum | Description |
|---|---|---|---|
| Update on launch | RDCONFIG_UPDATE_MODE_APP_START (1<<0) | START_UP | Pull on app launch |
| Scheduled update | RDCONFIG_UPDATE_MODE_SCHEDUAL (1<<1) | PERIODIC | Pull at intervals |
| Update on foreground | RDCONFIG_UPDATE_MODE_ENTER_FOREGROUND (1<<2) | HOT_RELOAD (foreground after background exceeds threshold) | Android calls it HOT_RELOAD |
| Update on network recovery | RDCONFIG_UPDATE_MODE_NETWORK_CHANGE (1<<3) | NETWORK_RECONNECT | Pull when network reconnects from offline |
- Default interval: Scheduled updates default to 4 hours (iOS
updateDuration= 14400s; AndroidupdateIntervalrecommended greater than 1 hour) - Bit mask combination: iOS
updateMode = APP_START | SCHEDUAL | NETWORK_CHANGE; AndroidupdateStrategyuses the same bit operations
systemId (Subsystem Differentiation)
systemId distinguishes different subsystems under the same app to avoid configuration data mixing:
| systemId | Subsystem | Description |
|---|---|---|
| 10001 | Configuration (RDelivery default) | iOS/Android default value |
| 10010 | Resources (ResHub) | Used internally by resource SDK |
| 10021 | Hotfix (Fix) | Used internally by hotfix SDK |
| 10016 | Harmony Upgrade | Hardcoded in upgrade SDK |
| 10013 | TAB mode | Can be set in configuration SDK |
When integrating the configuration SDK, you typically do not need to explicitly set systemId (default 10001 is used). When integrating resource/upgrade SDKs, systemId is handled internally by the SDK.
Pull Target (PullTarget / target)
The C++ configuration layer (RDeliveryConfig.target) and resource layer (ResHubAppInfo.target) share the same concept, determining pull scope:
| Enum Value | C++ RDPullTarget | Meaning |
|---|---|---|
| Project level (0) | RDPullTargetProject | Pull only configurations/resources under the current project (default) |
| App level (1) | RDPullTargetApp | Pull configurations/resources at the entire app dimension |
| All (2) | RDPullTargetBoth | Pull both project-level and app-level |
- iOS corresponds to
RDConfigServerPullTarget(Project/App/AppAndProject) - Resource SDK's
ResHubTargetis isomorphic to this, mapped byreshub_rdelivery_creater - Most scenarios use the default Project; switch to App/Both when cross-project shared configuration is needed
Dependency Injection Pattern
All platform SDKs support key component dependency injection and provide default implementations. This is a core design of Shiply SDK:
| Component | Purpose | Default Implementation |
|---|---|---|
| Network | HTTP requests | iOS RDNetworkImpl (NSURLSession); Android HttpsURLConnectionNetwork; C++ INetwork |
| Storage | KV cache | iOS RDMMKVFactoryImpl (MMKV); Android MmkvStorageFactory; C++ RAFTKVStorageProtocol |
| Logging | SDK log output | iOS RDLoggerImpl (NSLog); Android SystemLog; C++ ILog |
| JSON | Model conversion | iOS RDeliveryJsonModelImpl (YYModel) |
| RSA/AES | Encryption/decryption | C++ IRSA/IAES (default implementations injected by platform) |
The C++ layer provides
IRSA/IAESinterfaces for encryption/decryption injection; each platform injects corresponding implementations during initialization.
Strongly recommend injecting a business logging implementation: Default logging implementations (NSLog/SystemLog) are not suitable for production. Inject your business logging component to output SDK logs to your business logging system for production troubleshooting. This is a common best practice across all platforms.
When custom injection is needed:
- Your integration uses modified MMKV/YYModel causing dependency conflicts
- You need a custom network layer (e.g., routing through a unified business network channel or adding proxies)
- MMKV is already initialized globally and you don't want the SDK to initialize it again
Resource Loading Strategies (Resource SDK Common)
ResHub has three resource loading semantics, consistent across platforms:
| Semantics | Method Prefix | Behavior |
|---|---|---|
| Locked Version (Lock) | resWithId / loadWithId | Returns the same version across multiple calls within a process; suitable for scenarios requiring consistent experience |
| Latest Version (Latest) | latestResWithId / loadLatestWithId | Returns the latest resource in local configuration; multiple calls may return different versions |
| Realtime Latest | loadRealtimeLatestWithId | Forces a real-time configuration request before fetching the latest package; high cost for frequent calls; use only for resources with extremely high real-time requirements |
res/getseries: Synchronous local read, no network requestloadseries: Asynchronous, may trigger network pullloadLatestreturns the "latest in local configuration", which may lag behind the platform latest; useloadRealtimeLatestfor real-time latest
Custom Attributes (custom_properties)
custom_properties is a key parameter for RequestFullRemoteData calls, used to match gray release rules by custom attributes:
- The business passes
custom_properties(key-value pairs) when pulling full data; the server matches corresponding gray release rules based on attribute values and delivers different configurations/resources - Typical attributes: user level (vip_level), region, A/B experiment group, etc.
- Not passing is equivalent to not participating in custom attribute matching; only default dimensions (userId/deviceId, etc.) are matched
- Platform implementations: iOS
RDeliverySDKSettings.customProperties; AndroidRDeliverySetting.customProperties; Harmonycustom_properties
Configuration Default Values
When reading configurations, if the remote end does not have the key / has not been pulled / web console has not set a value, defaultValue is returned:
- With
defaultValueparameter: Returns defaultValue - Without: Returns corresponding empty value (object nil, int 0, etc.)