Links

iOS

Add Auth Service to Your iOS Project

Prerequisites

  • Install the following:
    • Xcode 14.1 or later
    • CocoaPods 1.11.0 or higher
  • Make sure that your project meets the following requirements:
    • Your project must target these platform versions or later:
      • iOS 13

Create a Particle Project and App

Before you can add our Auth Service to your iOS app, you need to create a Particle project to connect to your iOS app. Visit Particle Dashboard to learn more about Particle projects and apps.

Add the Auth Service SDK to Your App

Auth Service supports installation with CocoaPds.
Auth Service's CocoaPods distribution requires Xcode 13.3.1 and CocoaPods 1.10.0 or higher. Here's how to install the Auth Service using CocoaPods:
  1. 1.
    Create a Podfile if you don't already have one. From the root of your project directory, run the following command:
pod init
2. To your Podfile, add the Auth Service pods that you want to use in your app:
pod 'ParticleAuthService'
3. Install the pods, then open your .xcworkspace file to see the project in Xcode:
pod install --repo-update
open your-project.xcworkspace
If you would like to receive release updates, subscribe to our GitHub repository.

Edit Podfile

// paste there code into pod file
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'YES'
end
end
end

Initialize Auth Service in your app

The final step is to add an initialization code to your application. You may have already done this as part of adding the Auth Service to your app. If you are using a quickstart sample project, this has been done for you.
  1. 1.
    Create a ParticleNetwork-Info.plist into the root of your Xcode project
  2. 2.
    Copy the following text into this file:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PROJECT_UUID</key>
<string>YOUR_PROJECT_UUID</string>
<key>PROJECT_CLIENT_KEY</key>
<string>YOUR_PROJECT_CLIENT_KEY</string>
<key>PROJECT_APP_UUID</key>
<string>YOUR_PROJECT_APP_UUID</string>
</dict>
</plist>
3. Replace YOUR_PROJECT_UUID, YOUR_PROJECT_CLIENT_KEY, and YOUR_PROJECT_APP_UUID with the new values created in your Dashboard
4. Import the ParticleNetwork module in your UIApplicationDelegate
Swift
Objective-C
import ParticleNetworkBase
import ParticleAuthService
@import ParticleNetworkBase;
@import ParticleAuthService;
5. Initialize the ParticleNetwork service, which is typically in your app's application:didFinishLaunchingWithOptions: method:
Swift
Objective-C
// select a network from ChainInfo.
let chainInfo = ParticleNetwork.ChainInfo.ethereum(.mainnet)
let devEnv = ParticleNetwork.DevEnvironment.debug
let config = ParticleNetworkConfiguration(chainInfo: chainInfo, devEnv: devEnv)
ParticleNetwork.initialize(config: config)
// also custom your evm network.
let chainInfo = ParticleNetwork.ChainInfo.customEvmNetwork(fullName: "Ethereum", network: "rinkeby", chainId: 4, explorePath: "https://rinkeby.etherscan.io/", symbol: "ETH")
// select a network from ChainName enum.
ChainInfo *chainInfo = [ChainInfo ethereum:EthereumNetworkMainnet];
DevEnvironment devEnv = DevEnvironmentDebug;
ParticleNetworkConfiguration *config = [[ParticleNetworkConfiguration alloc] initWithChainInfo:chainInfo devEnv:devEnv];
[ParticleNetwork initializeWithConfig:config];
// also custom your evm network.
ChainName *chainName = [ChainName customEvmNetworkWithFullName:@"Ethereum" network:@"rinkeby" chainId:4 explorePath:@"https://rinkeby.etherscan.io/" symbol:@"ETH" isSupportEIP1159:YES];
6. Add the scheme URL handle in your app's application(_:open:options:) method
Swift
Objective-C
return ParticleAuthService.handleUrl(url)
return [ParticleAuthService handleUrl:url];
7. Configure your app scheme URL, select your app from TARGETS, under Info section, click + to add the URL types, and paste your scheme in URL Schemes
Your scheme URL should be "pn" + your project app uuid.
For example, if your project app id is "63bfa427-cf5f-4742-9ff1-e8f5a1b9828f", your scheme URL is "pn63bfa427-cf5f-4742-9ff1-e8f5a1b9828f".
Config scheme url
devEnv needs to be modified to be DevEnvironment.production for release.

Dynamically switch the chain info:

Swift
Objective-C
// Async switch chain info, it will check if user has logged in this chain name.
// For example, if a user logged in with ethereum, then switch to bsc,
// it will switch to bsc directly, beacuse both bsc and ethereum are evm,
// but if switch to solana, beacuse user didn't log in solana before, it will
// present a web browser for additional information automatically.
let chainInfo = ParticleNetwork.ChainInfo.ethereum(.kovan)
ParticleAuthService.setChainInfo(chainInfo).subscribe { [weak self] result in
guard let self = self else { return }
switch result {
case .failure(let error):
print(error)
case .success(let userInfo):
print(userInfo)
}
}.disposed(by: bag)
// Sync switch chain info. it will wont check if user has logged in.
let chainInfo = ParticleNetwork.ChainInfo.ethereum(.kovan)
ParticleNetwork.setChainInfo(chainInfo)

API Reference

Login

To auth login with Particle, call ParticleNetwork.login(...)and subscribe. You can log in with your email or phone number by changing the LoginType parameter. Your wallet is created when you log in successfully for the first time.
Swift
Objective-C
/// Login
/// - Parameters:
/// - type: Login type, support email, phone, google, apple, facebook and so on.
/// - account: When login type is email or phone, you could pass email address or phone number.
/// When login type is jwt, you must pass json web token.
/// - supportAuthType: Controls whether third-party login buttons are displayed. default will show all third-party login buttons.
/// - loginFormMode: Controls whether show light UI in web, default is false.
/// - socialLoginPrompt: Social login prompt.
/// - Returns: User infomation single
ParticleAuthService.login(type: .email).subscribe { [weak self] result in
guard let self = self else { return }
switch result {
case .failure(let error):
// handle error
case .success(let userinfo):
// login success, handle userinfo
}
}.disposed(by: bag)
/// Login with JWT
let account = "json web token"
ParticleAuthService.login(type: .jwt, account: account).subscribe { [weak self] result in
guard let self = self else { return }
switch result {
case .failure(let error):
// handle error
case .success(let userinfo):
// login success, handle userinfo
}
}.disposed(by: bag)
[ParticleAuthService loginWithType:LoginTypeEmail successHandler:^(UserInfo * userInfo) {
NSLog(@"%@", userInfo);
[self showLogin:NO];
} failureHandler:^(NSError * error) {
NSLog(@"%@", error);
}];
After log-in success, you can obtain user info by calling ParticleNetwork.getUserInfo()

Is user login

Swift
Objective-C
ParticleAuthService.isLogin()
[ParticleAuthService isLogin]

Logout and FastLogout

The SDK will delete user's account information in cache.
Swift
Objective-C
// This method presents a safari view controller, please keep the presented view controller alive,
// let safari view controller close automaticlly, then you will get the result.
ParticleAuthService.logout().subscribe { [weak self] result in
guard let self = self else { return }
switch result {
case .failure(let error):
// handle error
case .success(let success):
// logout success
}
}.disposed(by: bag)
// This method do logout in a slient way.
ParticleAuthService.fastLogout().subscribe { [weak self] result in
guard let self = self else { return }
switch result {
case .failure(let error):
// handle error
case .success(let success):
// logout success
}
}.disposed(by: bag)
[ParticleAuthService logoutWithSuccessHandler:^(NSString * result) {
NSLog(@"%@", result);
[self showLogin:YES];
} failureHandler:^(NSError * error) {
NSLog(@"%@", error);
}];

Get user info and address after login

Swift
Objective-C
ParticleAuthService.getUserInfo()
ParticleAuthService.getAddress()
[ParticleAuthService getUserInfo];
[ParticleAuthService getAddress];

Custom modal present style

Swift
// support fullScreen and formSheet
// default web broswer modal present style is formSheet
ParticleAuthService.setModalPresentStyle(.fullScreen)
// Set safari page show in medium screen, this method works from iOS 15
// default value is false.
// if you want to use medium screen, you must setModalPresentStyle fullScreen
ParticleAuthService.setMediumScreen(true)

Custom interface style

Swift
// set interface style, default value if follow system.
// *If you are using ParticleWalletGUI, you should call
// ParticleWalletGUI.setInterfaceStyle instead.
// set dark mode
ParticleNetwork.setInterfaceStyle(.dark)

Set display wallet

Swift
// set display wallet when call sign and send transaction.
ParticleAuthService.setDisplayWallet(true)

Set language

// Default value is unspecified, that follows user system language.
// *If you are using ParticleWalletGUI, you should call
// ParticleWalletGUI.setLanguage instead
// set English language
ParticleNetwork.setLanguage(Language.en)

Signatures

Use the Particle SDK to sign a transaction or message. The SDK provides three methods for signing:
  1. 1.
    signAndSendTransaction: sign and send the transaction with Particle Node, then return the signature. This supports both Solana and EVM.
  2. 2.
    signTransaction: sign transaction, return signed message. This only supports Solana.
  3. 3.
    signMessage: sign message, return signed message. This supports both Solana and EVM.
  4. 4.
    signTypedData: sign typed data; this supports v1, v3, and v4 typed data. Return signed message; this only supports EVM.
Swift
Objective-C
//transaction: request base58 string in solana, or hex string in evm
ParticleAuthService.signAndSendTransaction(transaction).subscribe { [weak self] result in
guard let self = self else { return }
switch result {
case .failure(let error):
// handle error
case .success(let signature):
// handle signature
}
}.disposed(by: bag)
//transaction: request base58 string in solana, not support evm
ParticleAuthService.signtransaction(transaction).subscribe { [weak self] result in
guard let self = self else { return }
switch result {
case .failure(let error):
// handle error
case .success(let signedMessage):
// handle signed message
}
}.disposed(by: bag)
//transaction: request base58 string array in solana, not support evm
let transactions: [String] = []
ParticleAuthService.signAllTransactions(transactions).subscribe { [weak self] result in
switch result {
case .failure(let error):
print(error)
case .success(let signature):
print(signature)
}
}.disposed(by: self.bag)
//sign string, any string in solana, request hex string in evm
ParticleAuthService.signMessage(message).subscribe { [weak self] result in
guard let self = self else { return }
switch result {
case .failure(let error):
// handle error
case .success(let signedMessage):
// handle signed message
}
}.disposed(by: bag)
// sign typed data, request hex string in evm, not support solana.
// support v1, v3, v4 typed data
ParticleAuthService.signTypedData(message, version: .v1).subscribe { [weak self] result in
switch result {
case .failure(let error):
// handle error
case .success(let signed):
// handle signed message
}
}.disposed(by: bag)
//transaction: request base58 string in solana, or hex string in evm
[ParticleAuthService signAndSendTransaction:transaction successHandler:^(NSString * signature) {
NSLog(@"%@", signature);
} failureHandler:^(NSError * error) {
NSLog(@"%@", error);
}];
//transaction: request base58 string in solana, not support evm
[ParticleAuthService signTransaction:transaction successHandler:^(NSString * signedTransaction) {
NSLog(@"%@", signedTransaction);
} failureHandler:^(NSError * error) {
NSLog(@"%@", error);
}];
//sign string, any string in solana, request hex string in evm
[ParticleAuthService signMessage:message successHandler:^(NSString * signedMessage) {
NSLog(@"%@", signedMessage);
} failureHandler:^(NSError * error) {
NSLog(@"%@", error);
}];
// sign typed data, request hex string in evm, not support solana.
// support v1, v3, v4 typed data
[ParticleAuthService signTypedData:message successHandler:^(NSString * signedMessage) {
NSLog(@"%@", signedMessage);
} failureHandler:^(NSError * error) {
NSLog(@"%@", error);
}];
You can create a transaction with TxData and FeeMarketEIP1559TxData There's an easy way to do this with Wallet Service.

Open web wallet

Swift
// if user is login, it will open web wallet.
ParticleAuthService.openWebWallet()

Open account and security

ParticleAuthService.openAccountAndSecurity()

Set security account config

// set security account config,
// promptSettingWhenSign default value is 1.
// promptMasterPasswordSettingWhenLogin default value is 0.
// 0 no prompt
// 1 first time show prompt
// 2 every time show prompt
ParticleAuthService.setSecurityAccountConfig(config:
.init(promptSettingWhenSign: 1, promptMasterPasswordSettingWhenLogin: 2))

CheckSum support

import ParticleNetworkBase
/// Ethereum address checksum, follow EIP55.
/// Don't use it with solana address.
/// - Returns: Checksum Address
func toChecksumAddress() -> String
print("0x2648cfe97e33345300db8154670347b08643570b".toChecksumAddress())

TRON network support

import ParticleNetworkBase
// convert tron base58 address to hex address
let tronAddressHex = TronFormatAddress.toHex("TDTduRew1o2ZqP9wiDPVEqdywMQdNC4hto")
print(tronAddressHex) // 0x2648cfe97e33345300db8154670347b08643570b
// convert hex address to tron base58 address
let tronAddressBase58 = TronFormatAddress.fromHex("0x2648cfe97e33345300db8154670347b08643570b")
print(tronAddressBase58) // TDTduRew1o2ZqP9wiDPVEqdywMQdNC4hto

Particle Provider

// handle request from walle connect, could be used with ParticleWalletConnect
// support following methods:
// eth_sendTransaction, return signature or error
// eth_signTypedData, return signature or error
// personal_sign, return signature or error
// wallet_switchEthereumChain, return null or error
// eth_chainId, return chainId string like "0x5" or error
// eth_signTypedData_v1, return signature or error
// eth_signTypedData_v3, return signature or error
// eth_signTypedData_v4, return signature or error
public static func request(method: String, params: [Encodable]) -> Single<Data?>
// for example
ParticleProvider.request(method: method, params: params).subscribe { data in
// handle data
} onFailure: { error in
// handle error
}.disposed(by: bag)

Error

ParticleNetwork.Error contains error details. The error will be logged in debug DevEnvironment.

Particle Wallet Connect V1

Integrate your app as a wallet connect wallet. If you are using a quickstart sample project, this has been done for you.
Add Particle Wallet Connect with CocoaPods
pod 'ParticleWalletConnect'

API Reference

Initialize

// Initialize Particle Wallet Connect SDK, a wallet meta data
ParticleWalletConnect.initialize(
WalletMetaData(name: "Particle Wallet",
icon: URL(string: "https://connect.particle.network/icons/512.png")!,
url: URL(string: "https://particle.network")!,
description: nil))

Connect

// Connect to a wallet connect code
let wcCode = "wc:[email protected]?bridge=https%3A%2F%2Fbridge%2Ewalletconnect%2Eorg%2F&key=3da9dbb33b560beeb1750203a8d0e3487b4fe3fdd7b7953d79fbccadae8aab48"
ParticleWalletConnect.shared.connect(code: wcCode)

Set delegate in your controller or view model.

ParticleWalletConnect.shared.delegate = self
Handle connect result by implement ParticleWalletConnectDelegate protocol.
public protocol ParticleWalletConnectDelegate: AnyObject {
/// Handle request from dapp
/// - Parameters:
/// - topic: Topic
/// - method: Method name
/// - params: Params
/// - completion: Result, encode to data
func request(topic: String, method: String, params: [Encodable], completion: @escaping (Result<Data?>) -> Void)
/// Did connect session
/// - Parameter session: Session
func didConnectSession(_ session: Session)
/// Did disconnect session
/// - Parameter session: Session
func didDisconnect(_ session: Session)
/// Should start session, usually called after connect,
/// you could save session.topic for quert session and manage session.
/// - Parameters:
/// - session: Session
/// - completion: Should return public address and chain id.
func shouldStartSession(_ session: Session, completion: @escaping (String, Int) -> Void)
}

Get session

// Get wallet connect session by topic
let session = ParticleWalletConnect.shared.getSession(by: topic)

Remove session

// Remove wallet connect session by topic
ParticleWalletConnect.shared.removeSession(by: topic)

Get all sessions

// Get all wallet connect sessions
let sessions = ParticleWalletConnect.shared.getAllSessions()

Update session

// updata wallet connect public address and chain id.
ParticleWalletConnect.shared.update(session, publicAddress: publicAddress, chainId: chainId)

Disconnect

// Disconnect wallet connect session
ParticleWalletConnect.shared.disconnect(session: session)
Last modified 8d ago