Is there any way to access the last time an ABAddressBook contact was accessed, interacted with, called, miss-called, etc.
I'm aware of the ABPerson properties, specifically kABPersonModificationDateProperty. But I was wondering if there any way of knowing more about the users interaction with that contact.
No apple does not allow access to the Call list. Since a call information is stored in the call and not in the addressbook there is no way to get the information you want from the addressbook.
I don't think you can access called history in iOS, especially after iOS 4. You can however know that a phone call was dialled using CoreTelephony framework.
I do it in applicationDidBecomeActive of my AppDelegate.m
...
typeof(self) __weak weakSelf = self;
self.center = [[CTCallCenter alloc]init];
self.center.callEventHandler = ^(CTCall *call) {
if(call.callState == CTCallStateDialing) {
weakSelf.callWasMade = YES;
}
};
...
Related
Using the FBSDK mentioned in the title of this question, I present a simple share dialog in a view controller:
// Setup the content for the share
FBSDKShareLinkContent *content = [[FBSDKShareLinkContent alloc] init];
content.contentURL = linkUrl;
content.contentDescription = description;
content.contentTitle = title;
content.imageURL = imageUrl;
// Show the share dialog
[FBSDKShareDialog showFromViewController:controller
withContent:content
delegate:someDelegate];
And implement the delegate method...
- (void)sharer:(id<FBSDKSharing>)sharer didCompleteWithResults:(NSDictionary *)results
{
NSLog(#"Sweet, they shared.");
}
So far so good, as long as the user has the Facebook application installed on their device. The issue arises when the user does not have Facebook installed. If this is the case, Safari opens up to a web version of Facebook's login flow (this is fine), but if you then switch back to the original application without logging into Facebook / performing any additional tasks, the completion delegate method shown above is called.
Does anyone have any experience with a workaround for this? It seems like there should be a reliable way for determining whether or not the post did indeed occur.
Note: The above code is pretty pseudo-ish. In the actual implementation I have indeed implemented all of the delegate call backs (didComplete, didCancel, and didFail).
Edit: It turns out, the results dictionary is empty when the completion method is called if the Facebook app is installed on the device. To overcome this, a check needs to be done to see if Facebook is installed first.
Of course after posting I stumbled upon the answer. The results dictionary returned in the didCompleteWithResults method contains a postId key if the share actually occurred. So the logic is as simple as:
- (void)sharer:(id<FBSDKSharing>)sharer didCompleteWithResults:(NSDictionary *)results
{
NSURL *fbURL = [NSURL URLWithString:#"fb://"];
if (![[UIApplication sharedApplication] canOpenURL:fbURL])
if (results[#"postId"]) {
NSLog(#"Sweet, they shared, and Facebook isn't installed.");
} else {
NSLog(#"The post didn't complete, they probably switched back to the app");
}
} else {
NSLog(#"Sweet, they shared, and Facebook is installed.");
}
}
Although this works, it doesn't seem to be a very safe way of going about things (what if Facebook changes the key from "postId" to something else in the future? Unlikely but you get my point).
I'm trying to test out the iOS 8.1 handoff feature with NSUserActivity between my iPhone and my iPad. For this, I tried both implementing my own solution, and to use Apple's PhotoHandoff project. However, it's not working.
If I provide a webpageURL, the handover works fine, but when I try to use userData or addUserInfoEntriesFromDictionary nothing works, and I can't for the life of me figure out what the catch is to make the data work.
Sample code:
NSUserActivity *activity = [[NSUserActivity alloc] initWithActivityType:#"com.company.MyTestApp.activity"];
activity.title = #"My Activity";
activity.userInfo = # {};
// activity.webpageURL = [NSURL URLWithString:#"http://google.com"];
self.userActivity = activity;
[self.userActivity becomeCurrent];
[self.userActivity addUserInfoEntriesFromDictionary:# { #"nanananan": #[ #"totoro", #"monsters" ] }];
(I'm also unable to make it work with a Mac app with a corresponding activity type)
I hope you found the solution already, but in case somebody stumbles upon this problem too, here is a solution. (Actually not very different from the previous answer)
Create user activity without userInfo, it will be ignored:
NSUserActivity *activity = [[NSUserActivity alloc] initWithActivityType:#"..."];
activity.title = #"Test activity";
activity.delegate = self;
activity.needsSave = YES;
self.userActivity = activity;
[self.userActivity becomeCurrent];
Implement the delegate to react to needSave events:
- (void)userActivityWillSave:(NSUserActivity *)userActivity {
userActivity.userInfo = #{ #"KEY" : #"VALUE" };
}
When needsSave is set to YES this method will be called and userActivity will be updated.
Hope this helps.
To update the activity object’s userInfo dictionary, you need to configure its delegate and set its needsSave property to YES whenever the userInfo needs updating.
This process is described in the best practices section of the Adopting Handoff guide.
For example, with a simple UITextView, you need to specify the activity type ("com.company.app.edit") identifier in the Info.plist property list file in the NSUserActivityTypes array, then:
- (NSUserActivity *)customUserActivity
{
if (!_customUserActivity) {
_customUserActivity = [[NSUserActivity alloc] initWithActivityType:#"com.company.app.edit"];
_customUserActivity.title = #"Editing in app";
_customUserActivity.delegate = self;
}
return _customUserActivity;
}
- (void)textViewDidBeginEditing:(UITextView *)textView
{
[self.customUserActivity becomeCurrent];
}
- (void)textViewDidChange:(UITextView *)textView
{
self.customUserActivity.needsSave = YES;
}
- (BOOL)textViewShouldEndEditing:(UITextView *)textView
{
[self.customUserActivity invalidate];
return YES;
}
- (void)userActivityWillSave:(NSUserActivity *)userActivity
{
[userActivity addUserInfoEntriesFromDictionary:#{ #"editText" : self.textView.text }];
}
FWIW, I was having this issue. I was lucky that one of my Activity types worked and the other didn't:
Activity: Walking
(UserInfo x1,y1)
(UserInfo x2,y2)
(UserInfo x3,y3)
Activity: Standing
(UserInfo x4,y4)
Activity: Walking
etc.
I got userInfo if the handoff occured when standing but not walking. I got other properties such as webpageURL in all cases; just userInfo came through null.
The fix for me was to invalidate & recreate the NSUserActivity object every time (e.g. when Walking to x2/y2 from x1/y1), instead of only when Activity type changed (e.g. from walking to standing). This is very much not the way the doc is written, but fixed the issue on iOS 9.
UPDATE: This workaround doesn't work on iOS 8. You need to implement this via the userActivityWillSave delegate, as gregoryM specified. Per Apple's doc:
To update the activity object’s userInfo dictionary efficiently,
configure its delegate and set its needsSave property to YES whenever
the userInfo needs updating. At appropriate times, Handoff invokes the
delegate’s userActivityWillSave: callback, and the delegate can update
the activity state.
This isn't a "best practice", it is required!
[Note: issue occurred on iOS 9 devices running code built on Xcode 6.x. Haven't tested Xcode 7 yet, and issue may not occur on iOS 8.]
I have two kontakt.io Beacons. I'm able to find it using the default Kontakt.io app available in the AppStore. But when I use the SDK and try to find it in my custom app, the app requests Bluetooth, which means it does something with it, but no beacons are found.
According to the documentation I must only create an object of KTKBeaconManager class, assign a KTKBeaconManagerDelegate and call startFindingDevices method. After that the delegate should receive callbacks whenever devices in range changes. I extended the KTKBeaconManager with a class called BeaconManager. Here's its code (Yes I have imported everything and code compiles. I didn't put it here to save space.).
BeaconManager.h
#interface BeaconManager : KTKBeaconManager <KTKBluetoothManagerDelegate>
#end
BeaconManager.m
#implementation BeaconManager
- (instancetype)init
{
self = [super init];
if (self) {
//Setting the delegate to self
self.delegate = self;
}
return self;
}
- (void)bluetoothManager:(KTKBluetoothManager *)bluetoothManager didChangeDevices:(NSSet *)devices {
NSLog(#"Entered didChangeDevices. Devices size: %d", devices.count);
}
#end
Starting the search.
BeaconManager *beaconManager = [BeaconManager new];
[beaconManager startFindingDevices];
[beaconManager reloadDevices]; //Tells the manager to forget all devices and start searching again.
This is actually a sample code from the documentation, but it's not working. Anybody's going through something similar and has got a clue what to do?
Your beaconManager is most probably deallocated just after it's created. You have to move it to an instance variable.
It's not written that directly but you should know what's the scope of life for object - it should be a property if you want to have it working all the time etc.
I have read allot in previous threads about FacebookSDK vs SocialFramework but I cant find anything regarding the more specific area of FriendPicker.
I have a picture in my application. Right now I use SLcomposeView to post to Facebook which works great.
I now want to add the possibility to tag a facebookfriend in that picture and post the picture with the friend included.
I first followed the: FriendPicker example - FacebookDev
My LoadData function will however not load any data probably because it doesnt use the Facebook Account from settings.
I then tried the code from the provided Facebook FreindPicker example (From the FacebookSDK). I then get bounced to facebook sign in but I receive sign in error (Error: 2) probably because I am already signed in through settings?
How do I best design the application for handling this?
Can I include "friendpicking" in the SlComposeView or do I need to remove it and only use Facebook SDK?
Will be better if you can post some of your code... Im using the following example to invoke the FBFriendPickerViewController
- (IBAction)addTAG:(id)sender {
if (self.friendPickerController == nil) {
// Create friend picker, and get data loaded into it.
self.friendPickerController = [[FBFriendPickerViewController alloc] init];
self.friendPickerController.title = #"Select Friends";
self.friendPickerController.delegate = self;
}
[self.friendPickerController loadData];
[self.friendPickerController clearSelection];
// Present the friend picker
[self.friendPickerController presentModallyFromViewController:self
animated:YES
handler:^(FBViewController *sender, BOOL donePressed) {
if (donePressed) {
self.selectedFriends = self.friendPickerController.selection;
NSLog(#"list of friends: %#", self.selectedFriends);
}
}];
}
Regards
Edited// the Scrumptious example app contains all what you need. Download the las facebokk SDK for iOS, go to samples.
I used CoreTelephony framework introduced in iOS SDK 4.0 to know about Incoming call & its dropped state.
CTTelephonyNetworkInfo *tni = [[CTTelephonyNetworkInfo alloc] init];
callCenter = [[CTCallCenter alloc] init];
crtCarrierName = tni.subscriberCellularProvider.carrierName;
[callCenter setCallEventHandler:^(CTCall *call) {
if ([[call callState] isEqual:CTCallStateConnected]) {
//this call has just connected
} else if ([[call callState] isEqual:CTCallStateDisconnected]) {
//this call has just ended (dropped/hung up/etc)
}
}];
Can i use this event handler to track call state when my app is in background?
Can i also fetch incoming call phone number from CTCall object? or there is any other way around.
I dont want to use Private API.Is there way available from Apple iOS SDK?
No there is no way to do this in the official SDK, you can not use it in the background since it does not fall on of the background running categories unless you app does something else in the background then just monitoring the call.
You will never be able to get the phone number of the current call since this is private data Apple will not allow you to acces the data.