I'm developing a new App where I request users to sign up via the phone number, so that I can store it in Parse.com's database. I am doing it to use the same phone numbers to send push notifications.
I have been trying to accomplish this by using Twilio and Parse.com. I read the tutorial here and I tried to follow it without success.
Link to the tutorial here.
This is my cloud code (as seen in the URL linked above )
var twilio = require('twilio')('removed', 'removed');
Parse.Cloud.define("sendVerificationCode", function(request, response) {
var verificationCode = Math.floor(Math.random()*999999);
var user = Parse.User.current();
user.set("phoneVerificationCode", verificationCode);
user.save();
twilio.sendSms({
From: "+46 10 138 91 84",
To: request.params.phoneNumber,
Body: "Your verification code is " + verificationCode + "."
}, function(err, responseData) {
if (err) {
response.error(err);
} else {
response.success("Success");
}
});
});
Parse.Cloud.define("verifyPhoneNumber", function(request, response) {
var user = Parse.User.current();
var verificationCode = user.get("phoneVerificationCode");
if (verificationCode == request.params.phoneVerificationCode) {
user.set("phoneNumber", request.params.phoneNumber);
user.save();
response.success("Success");
} else {
response.error("Invalid verification code.");
}
});
And this is the code I call in Xcode:
NSString *number = #"0737879108";
NSDictionary *params = [NSDictionary dictionaryWithObject:number forKey:#"number"];
//NSLog(#"%#", params);
[PFCloud callFunctionInBackground:#"sendVerificationCode" withParameters:params block:^(id object, NSError *error) {
NSString *message = #"";
if (!error)
message = #"Your SMS invitation has been sent!";
} else {
message = #"Uh oh, something went wrong :(";
}
[[[UIAlertView alloc] initWithTitle:#"Invite Sent!"
message:message
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles:nil, nil] show];
}];
Why am I getting this error message?
TypeError: Cannot call method 'set' of null
at main.js:7:10 (Code: 141, Version: 1.6.1)
The error is pretty straightforward. You use user to call the set method. And it says that TypeError: Cannot call method 'set' of null. So, the problem is about you called user. Try to debug the user or check whether Parse.User.current() return proper user.
Related
Need create VPN connection L2TP on osx without Shared Secret
NSString *server = #"serverIP";
NSString *username = #"user";
NSString *password = #"pass";
const void* passwordData = [[password dataUsingEncoding:NSUTF8StringEncoding] bytes];
[vpnManager loadFromPreferencesWithCompletionHandler:^(NSError *error) {
if (error) {
NSLog(#"Load config failed [%#]", error.localizedDescription);
return;
}
NEVPNProtocol *p = (NEVPNProtocol *)vpnManager.protocolConfiguration;
if (!p) {
p = [[NEVPNProtocol alloc] init];
}
p.username = username;
p.serverAddress = server;
p.passwordReference = (__bridge NSData * _Nullable)(passwordData);
p.disconnectOnSleep = NO;
vpnManager.protocolConfiguration = p;
vpnManager.localizedDescription = #"L2TPOverIPSec";
vpnManager.enabled = YES;
[vpnManager saveToPreferencesWithCompletionHandler:^(NSError *error) {
if (error) {
NSLog(#"Save config failed [%#]", error.localizedDescription);
}
}];
}];
NEVPNConnection *connect = [vpnManager connection];
NSError *error1;
if ([connect startVPNTunnelAndReturnError: &error1]) {
NSLog(#"connect");
} else {
NSLog(#"not connect");
}
after building i get this error Missing protocol or protocol has invalid type, and other 2 protocols use IKE tunnel, what can u advice to me? other option is run terminal from code and add this string networksetup -connectpppoeservice VPNConnect but i dont know if it possible
I know this is the old question, but I'm here to note, that Network Extension framework (where NEVPNProtocol is from) can't go on with OSI level 2 protocols, which is L2TP. (https://forums.developer.apple.com/thread/29909)
It seems now (starting from iOS 8 and os x 10.10) the recommended way on Apple devices is to use built-in protocols, or implement your own but on L3 / L4: https://developer.apple.com/documentation/networkextension
(And so there is no public API for using L2TP)
No, you need use SCNetwork and Helper Tool (to get root access) With this link you will be able to create L2TP Protocol and connect with it.
This works even on the latest version MacOS 11 "Big Sure"
I'm implementing Google Drive Api for my mac application using Google API Client for REST Library below,
- (void)fetchFileList {
_fileList = nil;
_fileListFetchError = nil;
GTLRDriveService *service = self.service;
GTLRDriveQuery_FilesList *query = [GTLRDriveQuery_FilesList query];
// Because GTLRDrive_FileList is derived from GTLCollectionObject and the service
// property shouldFetchNextPages is enabled, this may do multiple fetches to
// retrieve all items in the file list.
query.fields = #"kind,nextPageToken,files(mimeType,id,kind,name,webViewLink,thumbnailLink,trashed)";
_fileListTicket = [service executeQuery:query
completionHandler:^(GTLRServiceTicket *callbackTicket,
GTLRDrive_FileList *fileList,
NSError *callbackError) {
// Callback
_fileList = fileList;
_fileListFetchError = callbackError;
_fileListTicket = nil;
NSLog(#"%#", fileList);
}];
}
Here the return value
GTLRDrive_FileList 0x6080002404e0: {kind:"drive#fileList" files:[5]}
There are 7 items on my drive but it returns only 5 items?
It may have something to do with your nextPageToken. It returned only the result of a certain page, not all of them.
Check this docs:
Sometimes a query may return a large number of results, which are
returned one page at a time. When a result object includes a
nextPageToken string, you can execute the query again; supply the
returned token as the pageToken property of the new query, fetching
the next set of results. You can repeat this until you reach the last
page, which will not inlude a nextPageToken string.
GTLServiceDrive *drive = ...;
GTLQueryDrive *query = [GTLQueryDrive queryForFilesList];
query.q = search;
[drive executeQuery:query completionHandler:^(GTLServiceTicket *ticket,
GTLDriveFileList *fileList,
NSError *error) {
if (error == nil) {
NSLog(#"Have results");
// Iterate over fileList.files array
} else {
NSLog(#"An error occurred: %#", error);
}
}];
Try the Drive sample from the iOS Quickstart on how to fetch Files properly. Here's a snippet:
/ Construct a query to get names and IDs of 10 files using the Google Drive API.
- (void)fetchFiles {
self.output.text = #"Getting files...";
GTLQueryDrive *query =
[GTLQueryDrive queryForFilesList];
query.pageSize = 10;
query.fields = #"nextPageToken, files(id, name)";
[self.service executeQuery:query
delegate:self
didFinishSelector:#selector(displayResultWithTicket:finishedWithObject:error:)];
}
I am creating a native IOS app by using the Sitecore Mobile SDK. So far I am able to read the items I need but I got stuck on reading the fieldvalue from a linked item in a Droplink field.
I use this code:
SCApiContext* context = [SCApiContext contextWithHost: #"http://<myhost>/-/item"];
SCItemsReaderRequest* request = [ SCItemsReaderRequest new ];
request.requestType = SCItemReaderRequestQuery;
request.request = #"/sitecore/content/Home/descendant::*[##templatename='Content item']";
request.flags = SCItemReaderRequestReadFieldsValues;
request.fieldNames = [ NSSet setWithObjects: #"Content title", #"Content author", #"Content introduction", #"Content date", #"Content body" , nil ];
[context itemsReaderWithRequest: request]( ^(id result, NSError* error)
{
NSArray* items = result;
for (SCItem* item in result)
{
// get the author
__block NSString *author = #"empty";
SCField *dropLinkField = [item fieldWithName: #"Content author"];
[dropLinkField fieldValueReader]( ^(id result, NSError *error)
{
if (!error)
{
SCItem *linkedItem = result;
// TODO: author is not yet filled
NSSet *fieldsSet = [NSSet setWithObjects:#"Firstname", nil];
// this method seems to be skipped
[linkedItem fieldsReaderForFieldsNames:fieldsSet]( ^(id result2, NSError *error2)
{
if (!error2)
{
NSDictionary *fields = result2;
SCField *field_ = [fields objectForKey: #"Firstname"];
author = field_.rawValue;
}
});
}
});
}
}
The original item is read and I can read the field values of the droplink field. It also seems that I can read the linked Item, because I can write it's itempath to the log. But when I try to read a field from the linked item, it fails and the "fieldsReaderForFieldsNames" method seems to be skipped.
I'm obviously doing something wrong here, but seem to overlook the issue...
EDIT:
I forgot to mention that I use Sitecore 7, not sure if it makes a difference.
I have added the lines above that creates the SCApiContext and SCItemReaderRequest.
I use anonymous access and in the "site settings" I use
itemwebapi.mode="StandardSecurity"
itemwebapi.access="ReadOnly"
itemwebapi.allowanonymousaccess="true"
I just thought that I found the issue, because I did not set the Field Remote Read rights on several fields. However, setting that permission did not resolve it and other fields without the Field Remote Read set, did return in the API.
Sitecore iOS SDK operations (from the list below) are executed asynchronously on the background operation queue.
* fieldValueReader
* fieldsReaderForFieldsNames
This does not guarantee that author data is downloaded at the moment you are accessing it.
Please use downloaded items and fields in the completion callback block to ensure they exist on your iPhone.
[linkedItem fieldsReaderForFieldsNames:fieldsSet]( ^(id result2, NSError *error2)
{
NSLog(#"Read author field");
if (!error2)
{
NSLog(#"No error");
NSDictionary *fields = result2;
SCField *field_ = [fields objectForKey: #"Firstname"];
author = field_.rawValue;
// Now all required fields will
// definitely be downloaded by the time you create a blog item
NSLog(#"voornaam: %#", author);
ParTechBlogItem *blogItem;
blogItem = [[ParTechBlogItem alloc] initWithTitle:[item fieldValueWithName:#"Content title"]
date:[item fieldValueWithName:#"Content date"]
intro:[item fieldValueWithName:#"Content introduction"]
author:author
text:[item fieldValueWithName:#"Content body" ]];
[weakSelf addBlogItem:blogItem];
}
I'm using Parse and I'm retrieving a class from the data browser titled: "usernames".
I get all the objects in the class, and store them in an array. I then want to search the array for a username, so that the user may login. I will do the same for the password. Here's my code:
- (IBAction)login:(id)sender
{
if ([usernameLogin.stringValue isEqualTo:#""] || [passwordLogin.stringValue isEqualTo:#""]) {
NSBeginAlertSheet(#"Error", #"OK", nil, nil, self.window, self, #selector(sheetDidEnd:resultCode:contextInfo:), NULL, NULL, #"Please fill in all fields.");
}
/* retrieve user from parse db */
PFQuery *usernameQuery = [PFQuery queryWithClassName:#"usernames"];
[usernameQuery findObjectsInBackgroundWithBlock:^(NSArray *usernames, NSError *error) {
NSString *userString = [NSString stringWithFormat:#"%#", usernameLogin.stringValue];
NSLog(#"USERS:\n %#", usernames);
int i;
for (i = 0; i < [usernames count]; i++) {
NSString *userFind = [usernames objectAtIndex:i];
if ([userString isEqualToString:userFind]) {
NSLog(#"FOUND!!!");
}
}
/*
if ([usernames indexOfObject:usernameLogin.stringValue]) {
NSLog(#"User: '%#' was found successfully!", usernameLogin.stringValue);
} else {
NSLog(#"User: '%#' doesn't exist in database, or password was incorrect!", usernameLogin.stringValue);
}
*/
}];
gameCont = [[CSGameController alloc] initWithWindowNibName:#"CSGameController"];
[gameCont showWindow:self];
[gameCont.window makeKeyAndOrderFront:nil];
_window.isVisible = false;
}
Can anyone explain what I'm doing wrong? I'm searching the database to see if the entered user exists. I setup a test user, and it still says it doesn't exist. Thanks so much!
Added:
int i;
for (i = 0; i < [usernames count]; i++) {
NSString *userFind = [usernames objectAtIndex:i];
NSLog(#"UserFind class = %#, value = %#", [userFind class], userFind);
}
Output:
[2438:303] UserFind class = PFObject, value = <usernames:kx7aG2xfkX:(null)> {
username = ryan;
}
It seems you're trying to do a lot of things here that just don't make sense. Please consider reading the Parse iOS Guide. All PFQueries return PFObjects. PFObjects are in many ways like NSDictionaries; they are a single record in a database and can be fetched or stored.
A PFQuery always returns one or more PFObjects. A PFQuery's results should almost always be scopable to be immediately useful. In this example, the equals condition could have been articulated with -[PFQuery whereKey:equalTo:]. It is much faster to let Parse do the search for you. This also lets you create UI powered by the query's results via PFQueryTableViewController.
Finally, please please please don't make your own login code. Your current code is easily hacked to not only allow anyone to log in as anyone, but to learn anyone's password as well. Use the built-in PFUser class for user accounts. It handles secure login, offline caching of credentials, password resets, email verification, you can let users log in with their Facebook or twitter accounts in addition to username/password, and Parse has built-in view controllers for logging in and creating accounts of PFUsers. PFUsers are also the way to secure your data; a PFACL is an Access Control List that lets you decide which PFUsers can read or write data.
The wrong thing here that you are trying to use isEqualToString: with userFind, which is PFObject.
Try comparing with its username property:
...
for (PFObject *aUsername in usernames)
{
NSString *userFind = [aUsername objectForKey:#"username"];
if ([userString isEqualToString:userFind]) {
NSLog(#"FOUND!!!");
}
}
Problem solved: I used Parse's User class. They have pre-existing methods for registering users, like I was trying to do here in my own classes. Their methods for registering are:
PFUser *user = [PFUser user];
user.email = emailField.stringValue;
user.username = usernameField.stringValue;
user.password = passwordField.stringValue;
[user signUpInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
I am working on an iOS5 application that will facilitate mobile payments between two users. As part of the payment process, the sender and the recipient need to communicate with a server. The server requires that both parties present their identities when an authentication challenge is initiated upon connection.
Currently, I have hard-coded the certificate process by utilizing the following two methods in my code:
NSURLConnection Delegate didReceiveAuthenticationChallenge
(void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge: (NSURLAuthenticationChallenge *)challenge
{
NSLog(#"Authentication challenge");
// Load Certificate
NSString *path = [[NSBundle mainBundle] pathForResource:#"PKCS12" ofType:#"p12"];
NSData *p12data = [NSData dataWithContentsOfFile:path];
CFDataRef inP12data = (__bridge CFDataRef)p12data;
SecIdentityRef myIdentity;
SecTrustRef myTrust;
extractIdentityAndTrust(inP12data, &myIdentity, &myTrust);
SecCertificateRef myCertificate;
SecIdentityCopyCertificate(myIdentity, &myCertificate);
const void *certs[] = { myCertificate };
CFArrayRef certsArray = CFArrayCreate(NULL, certs, 1, NULL);
NSURLCredential *credential = [NSURLCredential credentialWithIdentity:myIdentity certificates:(__bridge NSArray*)certsArray persistence:NSURLCredentialPersistencePermanent];
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
}
C Method extractIdentityAndTrust
OSStatus extractIdentityAndTrust(CFDataRef inP12data, SecIdentityRef *identity, SecTrustRef *trust)
{
OSStatus securityError = errSecSuccess;
CFStringRef password = CFSTR("password");
const void *keys[] = { kSecImportExportPassphrase };
const void *values[] = { password };
CFDictionaryRef options = CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL);
CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL);
securityError = SecPKCS12Import(inP12data, options, &items);
if (securityError == 0) {
CFDictionaryRef myIdentityAndTrust = CFArrayGetValueAtIndex(items, 0);
const void *tempIdentity = NULL;
tempIdentity = CFDictionaryGetValue(myIdentityAndTrust, kSecImportItemIdentity);
*identity = (SecIdentityRef)tempIdentity;
const void *tempTrust = NULL;
tempTrust = CFDictionaryGetValue(myIdentityAndTrust, kSecImportItemTrust);
*trust = (SecTrustRef)tempTrust;
}
if (options) {
CFRelease(options);
}
return securityError;
}
I have tested this code numerous times and have been successful. Now I am trying to move on and allow the appropriate identity to be stored and then retrieved from the app's keychain. My objective is to allow users to import their P12 files via iTunes File Sharing or Dropbox and save them to the keychain.
I have looked at Apple's documentation for Getting and Using Persistent Keychain References and have been unable to figure out how to import the identity. Their code is a little confusing to me as they use undeclared variables/references (specifically the
&persistent_ref
variable). If anyone could help decipher it, that would be greatly appreciated.
TL;DR: How do I save the contents of a P12 file into my iOS5 app's keychain and retrieve it later to hand off to an NSURLConnection didReceiveAuthenticationChallenge method?
The following code should do the trick :
NSMutableDictionary *secIdentityParams = [[NSMutableDictionary alloc] init];
[secIdentityParams setObject:(id)myIdentity forKey:(id)kSecValueRef];
OSStatus status = SecItemAdd((CFDictionaryRef) secIdentityParams, NULL);
You interact with the Keychain by passing in a dictionary of key-value pairs that you want to find or create. Each key represents a search option or an attribute of the item in the keychain.
Keys are pre-defined constants that you must use depending on the type of data to be stored.
Those keys can be found in Apple's developer doc.
I think Apple's source code is indeed missing the allocation of persistentRef. They should have added such declaration at the beginning of the method :
NSData *persistentRef = nil;
Note that use of persistent reference is not mandatory. The above code should work just fine. As Apple explains it well :
Because a persistent reference remains valid between invocations of
your program and can be stored on disk, you can use one to make it
easier to find a keychain item that you will need repeatedly
source : https://developer.apple.com/library/ios/#documentation/Security/Conceptual/CertKeyTrustProgGuide/iPhone_Tasks/iPhone_Tasks.html#//apple_ref/doc/uid/TP40001358-CH208-DontLinkElementID_10
Swift 4.0
if let url = Bundle.main.url(forResource: "XXX", withExtension: "pem") {
let PKCS12Data = NSData(contentsOf: url)
let inPKCS12Data = CFDataCreate(kCFAllocatorDefault, PKCS12Data!.bytes.assumingMemoryBound(to: UInt8.self), (PKCS12Data?.length)!)
let keys: [CFString] = [kSecImportExportPassphrase]
let values: [CFTypeRef] = []
let keysPointer = UnsafeMutablePointer<UnsafeRawPointer?>.allocate(capacity: keys.count)
keysPointer.initialize(to: keys)
let valuesPointer = UnsafeMutablePointer<UnsafeRawPointer?>.allocate(capacity: values.count)
valuesPointer.initialize(to: values)
let optionsDictionary = CFDictionaryCreate(kCFAllocatorDefault, keysPointer, valuesPointer, 1, nil, nil)
var items = CFArrayCreate(kCFAllocatorDefault, UnsafeMutablePointer<UnsafeRawPointer?>.allocate(capacity: 0), 0, nil)
let securityError = SecPKCS12Import(inPKCS12Data!, optionsDictionary!, &items)
if (securityError == 0) {
print("Certificate installed Successfully")
} else {
print("Certificate installation failed")
}
}