Skip to main content

System requirements

On devices that cannot receive positioning data, the SDK stops itself and does not affect the rest of your app.

Installing the SDK

1
In Xcode, choose [File] → [Add Package Dependencies…].
2
Enter the URL below in the search field at the top left.
3
Set Dependency Rule to Up to Next Major Version and the value to 0.2.2.
4
Click [Add Package] to add the OneS1ght library to your app target.

iOS permissions

Add all five usage descriptions below to Info.plist. None of them can be left out. Add them to the list in the [Info] tab of your app target in Xcode.
1

Four String keys

Hover over a row, click the [+] that appears, type the key name in Key and the text in Value. Type is String.
2

One Dictionary key

NSLocationTemporaryUsageDescriptionDictionary has two levels.
  1. [+] → type the key name in Key → change Type to Dictionary (leave Value empty).
  2. Expand the ▸ on the left of the row, then click [+] on that row → Key Positioning, Type String, and the text in Value.
3

Check

You are done when all five entries appear in the list. It is fine if the section header reads Custom macOS Application Target Properties.
For Value you can use the <string> values below as they are. To write to the file directly instead of using the Xcode UI, see the Appendix.
Info.plist

Initializing the SDK

The SDK must be initialized before its internal engine can run. The Objective-C bridge exposes methods with the same names and returns results through a completion block.
Register bridge callbacks (onPosition, onZoneEnter, onFloorDetected, onConfigChanged, onStopped, etc.) only after initialize succeeds. Registering earlier has no effect (onDebugLog is the exception).

Profiles

Each user (account or device) is tracked as a profile.
Profile IDs are unique and cannot be recovered once lost, so store them carefully.

Creating a profile

Creating a profile returns its profile ID. Attributes are used as segments in reports and metrics, and there are no restrictions on the key-value pairs.
Store the returned ID in your app (or on your server) and link it with identify before positioning on every launch.
Do not put sensitive data such as names, phone numbers or member IDs in profile attributes.
Use only non-identifying values such as an age band ("20s").

Fetching a profile

Fetches the personalization attributes stored for a profile ID.

Updating a profile

Personalization attributes are replaced as a whole. The previous values are deleted and cannot be restored.

Deleting a profile

Deletes the profile’s personalization attributes. Deleted attributes cannot be restored.

Selecting a building and floor

Selecting a floor is optional. Without it, the positioning engine finds the floor from the locators’ BLE signals and still delivers coordinates.
To receive zone events, however, you must set the floor (see Zone events).

Selecting from BLE

When the SDK’s positioning engine finds a floor from locator BLE signals, the floor ID arrives in onFloorDetected.
nil arrives when the floor is lost.

Selecting manually

Set the building and floor yourself when the user picks the floor, or when you want to draw the map before positioning starts.

Receiving live positions

Get a positioning session with floorSession(), start it with begin() and stop it with end().
Positions arrive in onPosition as coordinates in meters, at the rate the engine produces them.
Only the coordinates uploaded to the server are downsampled to the console-configured rate (4 per second by default).

Zone events

Receive enter, exit and dwell events for the zones drawn in the console’s Space Management. Detection happens on the device, so events arrive immediately.
Campaigns attached to a zone (coupons, signage, etc.) are matched by the server and delivered through onTriggers.
The zone list comes from the floor set with setFloorMap. Without a floor, the zone list is empty, so onZoneEnter / onZoneExit never fire and E3009 is logged.

Refreshing zone data

onConfigChanged is called when zone data changes in the console. The SDK does not throttle these calls.
Each zone reload restarts enter/exit detection from scratch, so collapse bursts in your app (about 1 second) and handle them once.

Displaying the floor plan

You can display the floor plan the locators are installed on, together with the user’s current position.
If no floor plan is set, the background is shown as a grid.

Other options

Controlling data upload

Coordinates are uploaded automatically when 300 have been buffered, and every 60 seconds from begin() (a 300-point upload does not restart the 60-second timer).
Remaining coordinates are also uploaded when the app enters the background and on end(). If the app is force-quit, buffered coordinates are discarded.

Resetting the session

Stops positioning and discards the session. The stored key is cleared too, so APIs throw notInitialized until you call initialize again.
Use it to switch to another key without rebuilding the app.

Handling positioning shutdown

When the positioning engine shuts down, onStopped fires and you can bring the app back to a state where positioning can start again.

Checking device support

deviceAvailability can be read right away without a network (internet) connection.
Devices that do not support positioning do not affect the rest of your app.

Appendix

Writing Info.plist directly

The list shown in Xcode’s [Info] tab is actually the contents of a file named Info.plist. Projects created with recent versions of Xcode do not show this file and generate it at build time, so to write to it directly you first have to create it. This method also works if Xcode crashes while you add the Dictionary key.
1

Check whether the file exists

If Info.plist is visible in the Project Navigator on the left, skip to step 3.
2

Create the file

In [File] → [New] → [File from Template…] choose Property List, name it Info.plist and save it in the app target folder. Then search for Info.plist File in the [Build Settings] tab and set its value to TargetName/Info.plist. Leave Generate Info.plist File set to Yes — Xcode merges the generated entries with this file.
3

Paste the XML

Right-click Info.plist → Open As → Source Code, then paste the XML from iOS permissions between <dict> and </dict>.

Requesting permission (Nearby Interaction)

Locator positioning uses Apple’s Nearby Interaction. requestPermission() shows the system permission prompt, and the user decides whether to allow it.
Once denied, the app cannot ask again, so guide the user to turn the permission on in Settings.

Always location permission

On iOS 27.2 and later, location access must be ‘Always’ for the floor to be detected (BLE beacon region monitoring). On iOS 27.1 and earlier, ‘While Using the App’ is enough.
The SDK does not request ‘Always’. Without it the SDK still starts but cannot find the floor. If the user declined, guide them to Settings.

Debug logs

To see debug logs, register the handler right before calling initialize.
Logs printed with print as below appear in the Xcode debug console.

Troubleshooting

Error codes

Explains the errors you may run into during development.