The purpose Swift URL Components in iMessage Apps? - ios

I am brand new to iMessage App development. Looking at some examples, it looks like the way information is transferred from the sender to the recipient with iMessage Apps is via URLComponents.
Is this the only way to send information on iMessage Apps?
I am unfamiliar with URLComponents in swift, does the actual URL even matter?
Thanks!!

MSMessage's url property is where you can store your custom data.
You can use iMessageDataKit library for storing key-value pairs in MSMessage objects. It makes setting and getting data really easy like:
let message: MSMessage = MSMessage()
message.md.set(value: 7, forKey: "user_id")
message.md.set(value: "john", forKey: "username")
message.md.set(values: ["joy", "smile"], forKey: "tags")
print(message.md.integer(forKey: "user_id")!)
print(message.md.string(forKey: "username")!)
print(message.md.values(forKey: "tags")!)
(Disclaimer: I'm the author of iMessageDataKit)

You can use it w/ native swift as well:
let layout = MSMessageTemplateLayout()
var components = URLComponents()
let caption = URLQueryItem(name: "caption", value: self.melody)
let decodedMelody = URLQueryItem(name: "melody", value: self.melody)
components.queryItems = [caption, decodedMelody]
let message = MSMessage(session: session ?? MSSession())
layout.image = self.screenImage.image
layout.caption = "Melody built with haptic and vibro."
layout.subcaption = "sent via iVibrio"
message.summaryText = "something summary"
message.url = components.url!
message.layout = layout
Here's my complete example how to send data and image via iMessage application

Related

XMPP : How to parse XMPPResultSet with swift to retrieve chat history.(XMPP Chat History)

I'm developing an iOS Chat Application using XMPP and i'm trying to retrieve chat history in it.
For that I'm doing code as below
let newAllData = "my JID"
let value = DDXMLElement(name: "value", stringValue: newAllData)
let child = DDXMLElement(name: "field")
child.addChild(value)
child.addAttribute(withName: "var", stringValue: "with")
let set = XMPPResultSet(max: 5, before: "")
xmppMAM = XMPPMessageArchiveManagement()
xmppStream = XMPPStream()
xmppMAM.activate(xmppNewController.xmppStream)
xmppMAM.retrieveMessageArchive(at: nil, withFields: [child], with: set)
xmppMAM.addDelegate(self, delegateQueue: DispatchQueue.main)
however i'm passing max 5 into XMPPResultSet , i'm getting total messages count instead of 5 messages in XMPPMessageArchiveManagementDelegate methods as below.
func xmppMessageArchiveManagement(_ xmppMessageArchiveManagement: XMPPMessageArchiveManagement, didReceiveMAMMessage message: XMPPMessage) {
print("All Data = (message)")
}
func xmppMessageArchiveManagement(_ xmppMessageArchiveManagement: XMPPMessageArchiveManagement, didFinishReceivingMessagesWith resultSet: XMPPResultSet) {
}
in didFinishReceivingMessagesWith , i'm getting resultset count but how can i parse that using swift to retrieve history using this method.
or if you have any other way to find XMPP Chat History then also let me know in solution. I'm using ejjaberd with XMPP.
Any help with this would be appreciated. Thanks.

How to Send Bitcoin from one Wallet to Another Wallet in Swift 4

I am in the process of developing a custom Bitcoin wallet, I am able to generate the public/private keys by using Yenom/BitcoinKit. I need to send BTC to another wallet for which I am trying to use BitcoinKit. But I could not send Btc. How do I do this? can we use another Library other than BitcoinKit to send Btc from one wallet to another Wallet ?
So how do I transfer BTC from one wallet to another in Swift, please
advise.
Please check the following link
https://github.com/yenom/BitcoinKit/blob/master/Examples/Wallet/Wallet/SendViewController.swift
There is a function called sendToSomeAddress
private func sendToSomeAddress(_ amount: Int64) {
let toAddress: Address = try! AddressFactory.create("bchtest:qpytf7xczxf2mxa3gd6s30rthpts0tmtgyw8ud2sy3")
let changeAddress: Address = try! AppController.shared.wallet!.changeAddress()
var utxos: [UnspentTransaction] = []
for p in payments {
let value = p.amount
let lockScript = Script.buildPublicKeyHashOut(pubKeyHash: p.to.data)
let txHash = Data(p.txid.reversed())
let txIndex = UInt32(p.index)
print(p.txid.hex, txIndex, lockScript.hex, value)
let unspentOutput = TransactionOutput(value: value, lockingScript: lockScript)
let unspentOutpoint = TransactionOutPoint(hash: txHash, index: txIndex)
let utxo = UnspentTransaction(output: unspentOutput, outpoint: unspentOutpoint)
utxos.append(utxo)
}
let unsignedTx = createUnsignedTx(toAddress: toAddress, amount: amount, changeAddress: changeAddress, utxos: utxos)
let signedTx = signTx(unsignedTx: unsignedTx, keys: usedKeys())
peerGroup?.sendTransaction(transaction: signedTx)
}
I hope this will help

Sign any message with the user’s private key and verify the signature on Ethereum

I'm trying to explore Ethereum and creating a app which let user sign message and validate the message.
I'm using web3swift framework for this and what I have tried so far is as follows -
let web3Rinkeby = Web3.InfuraRinkebyWeb3()
let msgStr = "This is my first Ethereum App";
let data = msgStr.data(using: .utf8)
let signMsg = web3Rinkeby.wallet.signPersonalMessage(data!, account: address);
print(signMsg);
but I'm not sure if this is right and how to validate any message as well. Please help.
Seems, that you didn't specify exact address.
Here is an example:
let web3Rinkeby = Web3.InfuraRinkebyWeb3()
///
let keystore = try! EthereumKeystoreV3(password: "")
let keystoreManager = KeystoreManager([keystore!])
web3Rinkeby.addKeystoreManager(keystoreManager)
let address = keystoreManager.addresses![0]
///
let msgStr = "This is my first Ethereum App";
let data = msgStr.data(using: .utf8)
let signMsg = web3Rinkeby.wallet.signPersonalMessage(data!, account: address);
print(signMsg);
Here is an example, how to sign transactions in the tests of the project:

How to get a particular value from a Url in iOS - Swift 3

I have a url that is reg code attached to it. I just want to retrieve the reg code 7954741093-41547468-3 from the below url
https://mycode.funny.net/mycode/Registrations/7954741093-41547468-3?api-version=2011-04
You can use this:
let regCode:String = (url.components(separatedBy: "/").last?.components(separatedBy: "?").first)!
Where url is
let url:String = "https://mycode.funny.net/mycode/Registrations/7954741093-41547468-3?api-version=2011-04"
i think using URLComponents is a little more robust:
let url = "https://mycode.funny.net/mycode/Registrations/7954741093-41547468-3?api-version=2011-04"
let components = URLComponents(string: url)
components?.path.components(separatedBy: "/").last

TouchID with KeyChain - Enter Passcode screen appears malformed (Swift)

I am having a hard time with this one:
Our app uses TouchID to retrieve secrets from the KeyChain that are used to authenticate to a WebApp in a WKWebView. All is fine when the user successfully authenticates with TouchID.
The problem arises when the user fails TouchID and then taps on "Enter Passcode" to authenticate via device passcode instead. I noticed that the screen that gets presented is plain white, and the passcode text-box does not show a value for the last character entered until it is masked, creating a strange user experience. This seems like a bug to me, unless I am somehow missing a configuration requirement.
// global arguments for the touchId keychain queries
let kSecClassValue = NSString(format: kSecClass)
let kSecAttrAccountValue = NSString(format: kSecAttrAccount)
let kSecValueDataValue = NSString(format: kSecValueData)
let kSecClassGenericPasswordValue = NSString(format: kSecClassGenericPassword)
let kSecAttrServiceValue = NSString(format: kSecAttrService)
let kSecMatchLimitValue = NSString(format: kSecMatchLimit)
let kSecReturnDataValue = NSString(format: kSecReturnData)
let kSecMatchLimitOneValue = NSString(format: kSecMatchLimitOne)
let kSecAttrAccessControlValue = NSString(format: kSecAttrAccessControl)
let kSecUseOperationPromptValue = NSString(format: kSecUseOperationPrompt)
// set access control
let accessControl = SecAccessControlCreateWithFlags(kCFAllocatorDefault,
kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly, .UserPresence, nil)
// Instantiate a new default keychain query
// Tell the query to return a result
// Limit our results to one item
var keychainQuery: NSMutableDictionary = NSMutableDictionary(objects: [kSecClassGenericPasswordValue, service, userAccount, kCFBooleanTrue, kSecMatchLimitOneValue, "Place your finger to authenticate.", accessControl.takeUnretainedValue()], forKeys: [kSecClassValue, kSecAttrServiceValue, kSecAttrAccountValue, kSecReturnDataValue, kSecMatchLimitValue, kSecUseOperationPromptValue, kSecAttrAccessControlValue])
var dataTypeRef :Unmanaged<AnyObject>?
// Search for the keychain item
touchIdStatusCode = SecItemCopyMatching(keychainQuery, &dataTypeRef)
Here is the generated keychainQuery dictionary:
{
"accc" = "<SecAccessControlRef: 0x170621140>";
"acct" = “MY_ACCOUNT”;
"class" = genp;
"m_Limit" = "m_LimitOne";
"r_Data" = 1;
"svce" = “MY_SERVICE”;
"u_OpPrompt" = "Place your finger to authenticate.";
}
This behavior exists on the latest iOS version (8.4). Here is the screen I was referring to:
My question is: Am I somehow causing the screen to be broken by the way I am invoking TouchID? Or is this perfectly normal for this scenario?
Thanks, and sorry for the lengthy post!
The issue described is a bug that was confirmed by Apple engineers. It still exists as of iOS 9.0.2.

Resources