I'm using Estimote's iOS SDK and I'm trying to write the following Objective-C code in Swift:
[self.beaconConnection writeMajor:newMajor completion:^(unsigned short major, NSError *error)
{
if (error)
{
NSLog(#"Error major write: %#", error.localizedDescription);
}
self.majorTextFiled.text = [NSString stringWithFormat:#"%i", major];
}];
I'm struggling with getting the completion block to work.
Here's what I have so far:
beaconConnection.writeMajor(major, completion: { value, error in
}
)
I accidentally had major as Int and it's supposed to be UInt16 for that method.
Here's the updated code:
beaconConnection.writeMajor(UInt16(major), completion: { value, error in
}
)
Related
When one deletes one's account, one's session should be deleted as well.
However the methods exposed by Parse to do this are mutually exclusive, such that:
PFUser.currentUser()?.deleteInBackground()
PFUser.logOut()
can't be called in parallel or in sequence, even with completion handlers.
How is this achieved, excluding Cloud Code?
Please convert below code in Swift if necessary, it will works fine with me :
[[PFUser currentUser] deleteInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (succeeded && !error) {
[PFUser logOut];
}
else
{
NSLog(#"error: %#", error);
}
}];
Hope It's work fine...
Edit: Converted code to Swift
PFUser.currentUser()?.deleteInBackgroundWithBlock {
(succeeded: Bool, error: NSError?) -> Void in
if succeeded {
PFUser.logOut()
}
else {
NSLog("error: \(error)")
}
A part of code (I didn't write) is shown as deprecated in my Xcode project, here's the code block:
#pragma mark - Report Achievement Progress
static int reportAchievement(struct lua_State *state) {
[gameCenterAddOnInstance reportAchievementAction:[NSString stringWithCString:lua_tostring(state, 1) encoding:NSUTF8StringEncoding] percentComplete:(int)lua_tointeger(state, 2)];
return 1;
}
- (void) reportAchievementAction: (NSString*) identifier percentComplete: (float) percent
{
GKAchievement *achievement = [[GKAchievement alloc] initWithIdentifier: identifier];
if (achievement)
{
achievement.percentComplete = percent;
[achievement reportAchievementWithCompletionHandler:^(NSError *error)
{
if (error != nil)
{
NSLog(#"Error in reporting achievements: %#", error);
}
}];
}
}
According to Xcode, the depreciated part is:
reportAchievementWithCompletionHandler
Xcode suggests to use:
reportAchievements:WithCompletionHandler:
Instead. But, not being familiar with objective C, I wouldn't know where to start.
How to implement to new function?
Try this
[GKAchievement reportAchievements:#[achievement] withCompletionHandler:^(NSError *error)
{
if (error != nil)
{
NSLog(#"Error in reporting achievements: %#", error);
}
}];
Apple replaced the instance method - reportAchievementWithCompletionHandler: with the class method + reportAchievements:withCompletionHandler:. This allows you to report multiple achievements at once without having to call the instance method on every achievement object.
#[achievement] is shorthand for [NSArray arrayWithObjects:achievement, nil].
I'm trying to call a method from swift.
The method is in a singleton written in objective-C
the block in the header file:
typedef void(^VPersonResultBlock)(Person *person, NSError *error);
- (void)askForMe:(VPersonResultBlock)block;
and here's the implementation of that method.
- (void)askForMe:(VPersonResultBlock)block
{
if (_me) block(_me,nil);
else {
[Person getMeWithBlock:^(PFObject *person, NSError *error) {
if (!error) {
_me = (Person *)person;
block(_me,nil);
}
else if (error) {
block(nil,error);
}
else {
NSDictionary *userInfo = #{
NSLocalizedDescriptionKey: NSLocalizedString(#"Operation was unsuccessful.", nil),
NSLocalizedFailureReasonErrorKey: NSLocalizedString(#"The operation failed to retrieve the user.", nil),
NSLocalizedRecoverySuggestionErrorKey: NSLocalizedString(#"Check your network connection and try again", nil)
};
NSError *error = [[NSError alloc] initWithDomain:#"VisesAsyncErrorDomain" code:-10 userInfo:userInfo];
block(nil,error);
}
}];
}
}
In Objective-C, I can call this and it autocompletes without confusion.
[[VDataStore instance] askForMe:^(Person *person, NSError *error) {
// do things with myself that aren't strange
}];
Now let's say I want to call the same method from swift. The bridging header is setup, with the header file imported, but swift's expectation is confusing.
VDataStore.askForMe(VDataStore)
This is what shows up in the autocomplete options
(VPersonResultBlock!) -> Void askForMe(self: VDataStore)
what I was hoping for, was for this to autocomplete into a closure, and although it appears to see all of the information correctly, what it's expecting isn't lining up with what objective-C seems to understand.
How do I call this properly from swift?
Directly translate your ObjC calling code to Swift is
VDataStore.instance().askForMe() {
person, error in
// do things with myself that aren't strange
}
Your problem is that askForMe is instance method but you are accessing from class object VDataStore.askForMe. Swift will give you a function object that takes an instance as input.
I have been playing with icloud in the ios 8 beta, and the CloudKitAtlasAnIntroductiontoCloudKit sample project has been very helpful.
https://developer.apple.com/library/prerelease/ios/samplecode/CloudAtlas/Introduction/Intro.html
But I wanted to use the CKDiscoverAllContactsOperation class and I cannot find any sample code for it anywhere at all and the online documentation is not very helpful.
https://developer.apple.com/library/prerelease/ios/documentation/CloudKit/Reference/CKDiscoverAllContactsOperation_class/index.html
If anyone has managed to successfully use CKDiscoverAllContactsOperation could you please help point me in the right direction or show a working example of how it should be called?
I have tried this to see if I could even get an response from iCloud but nothing:
- (void)queryForRecordsOtherUsersInAddressBookcompletionHandler:(void (^)(NSArray *records))completionHandler {
CKDiscoverAllContactsOperation *discoverAllContactsOperation= [[CKDiscoverAllContactsOperation alloc] init];
[discoverAllContactsOperation setContainer:_container];
NSMutableArray *results = [[NSMutableArray alloc] init];
discoverAllContactsOperation.discoverAllContactsCompletionBlock = ^(NSArray *userInfos, NSError *operationError) {
[results addObjectsFromArray:userInfos];
};
discoverAllContactsOperation.discoverAllContactsCompletionBlock=^(NSArray *userInfos, NSError *operationError){
if (operationError) {
// In your app, handle this error with such perfection that your users will never realize an error occurred.
NSLog(#"An error occured in %#: %#", NSStringFromSelector(_cmd), operationError);
abort();
} else {
dispatch_async(dispatch_get_main_queue(), ^(void){
completionHandler(results);
});
}
};
}
and calling with this...
[self.cloudManager queryForRecordsOtherUsersInAddressBookcompletionHandler:^(NSArray *records ) {
if (records.count==0){
NSLog(#"Login name not found");
return;
}
//self.results= records;
//_loggedInRecord = self.results[0];
//NSLog(#"%#,%#",_loggedInRecord[#"lastName"],_loggedInRecord[#"firstName"]);
// [self performSegueWithIdentifier:#"loggedInSegue" sender:self ];
}];
I know the code shouldn't really do anything. Again I was just looking for a response from iCloud.
Here is what I am using. self.container is a CKContainer set with [CKContainer defaultContainer] in the init.
-(void)queryForAllUsers: (void (^)(NSArray *records))completionHandler {
CKDiscoverAllContactsOperation *op = [[CKDiscoverAllContactsOperation alloc] init];
[op setUsesBackgroundSession:YES];
op.queuePriority = NSOperationQueuePriorityNormal;
[op setDiscoverAllContactsCompletionBlock:^(NSArray *userInfos, NSError *error) {
if (error) {
NSLog(#"An error occured in %#: %#", NSStringFromSelector(_cmd), error);
//abort();
} else {
// NSLog(#"Number of records in userInfos is: %ld", (unsigned long)[userInfos count]);
dispatch_async(dispatch_get_main_queue(), ^(void){
completionHandler(userInfos);
});
}
}];
[self.container addOperation:op];
}
Before you can use the CKDiscoverAllContactsOperation operation, you first need to request for permission.
Pls use the method requestApplicationPermission:completion:
func discoverAllContacts() {
let container = CKContainer.defaultContainer()
//Request for user permission
container.requestApplicationPermission([.UserDiscoverability]) { [weak self] status, error in
switch status {
case .Granted where error == nil:
let operation = self?.discoverAllContactsOperation { usersInfo in
//do something here
}
if let operationExists = operation {
//Assuming there is a NSOperationQueue property called operationQueue
self?.operationQueue.addOperation(operationExists)
}
default:
break
}
}
}
func discoverAllContactsOperation(completionHandler: ([CKDiscoveredUserInfo]?) -> ()) -> NSOperation {
let operation = CKDiscoverAllContactsOperation()
operation.discoverAllContactsCompletionBlock = { usersInfo, error in
if error == nil {
print("Discoverd all contacts = \(usersInfo)")
completionHandler(usersInfo)
}
else {
print("Discoverd all contacts error = \(error)")
completionHandler(nil)
}
}
return operation
}
I am using the newest facebook SDK 3.8 for iOS. I want to post a comment to a wall post and I am having troubles. The following method I am using works maybe once or twice and then gives me the error:
Error: The operation couldn’t be completed. (com.facebook.sdk error 5.)
I am not sure if it has to do with "overdoing" posting because I am only posting twice when this happens and on different posts each time. Like I said, it happens out of no where (Everytime before it is a success). So I believe it is my code. Can anyone tell me if I am doing this right?
Thank you!
-(BOOL) postComment: (NSString *) postID :(NSString *) userPostMessage;
{
__block BOOL value;
postID=[NSString stringWithFormat:#"/%#/comments?message=%#",postID,userPostMessage];
[FBSession activeSession];
[FBRequestConnection startWithGraphPath:postID parameters:0 HTTPMethod:#"POST" completionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
BOOL temp;
if (error)
{
NSLog(#"Error: %#", [error localizedDescription]);
temp = TRUE;
}
else
{
NSLog(#"Result: %#", result);
valueReturned = (NSString*)result;
temp = FALSE;
}
value = temp;
}];
return value;
}