Skip to content

Instantly share code, notes, and snippets.

@roblav96
Created November 9, 2016 20:52
Show Gist options
  • Select an option

  • Save roblav96/cc38ca9c2bbb6df6446a16a7cbc379e4 to your computer and use it in GitHub Desktop.

Select an option

Save roblav96/cc38ca9c2bbb6df6446a16a7cbc379e4 to your computer and use it in GitHub Desktop.
nativescript-contacts-picker
export function pickContacts(): Promise<ContactsPickerItem> {
return new Promise(function(resolve, reject) {
let reqid: number = Math.floor(Math.random() * 999)
function onActivityResult(args: application.AndroidActivityResultEventData) {
Utils.parseActivityResult(args, reqid, resolve, reject)
}
application.android.addEventListener(application.AndroidApplication.activityResultEvent, onActivityResult)
Utils.uiAsync(() => {
let intent: android.content.Intent = new android.content.Intent(android.content.Intent.ACTION_PICK)
intent.setType(android.provider.ContactsContract.CommonDataKinds.Phone.CONTENT_TYPE)
let activity: android.app.Activity = application.android.foregroundActivity
activity.startActivityForResult(intent, reqid)
})
}).then(function(intent: android.content.Intent) {
let context: android.content.Context = application.android.context
let uri: android.net.Uri = intent.getData()
let cursor: android.database.Cursor = context.getContentResolver().query(
uri,
[
android.provider.ContactsContract.CommonDataKinds.Phone.NUMBER,
],
null,
null,
null
)
if (cursor == null || !cursor.moveToFirst()) {
return Promise.reject('cursor == null')
}
let result: any = Utils.getJsonFromCursor(cursor)
return Promise.resolve(result[android.provider.ContactsContract.CommonDataKinds.Phone.NUMBER])
}).then(function(phone: string) {
return new Promise(function(resolve, reject) {
let uri: android.net.Uri = android.net.Uri.withAppendedPath(
android.provider.ContactsContract.PhoneLookup.CONTENT_FILTER_URI,
android.net.Uri.encode(phone)
)
com.roblav96.nativescriptplayground.Threads.getContentProviderAsync(
application.android.context,
uri,
[
android.provider.ContactsContract.ContactsColumns.LOOKUP_KEY,
android.provider.ContactsContract.ContactsColumns.DISPLAY_NAME,
android.provider.ContactsContract.ContactsColumns.PHOTO_URI,
android.provider.ContactsContract.ContactsColumns.PHOTO_THUMBNAIL_URI,
android.provider.ContactsContract.ContactsColumns.PHOTO_ID,
android.provider.ContactsContract.PhoneLookupColumns.NUMBER,
android.provider.ContactsContract.PhoneLookupColumns.NORMALIZED_NUMBER,
android.provider.ContactsContract.PhoneLookupColumns.TYPE,
],
null,
null,
null,
true
).continueWith(new bolts.Continuation({
then: function(task: bolts.Task) {
Utils.parseContinuation(task, resolve, reject)
}
}))
})
}).then(function(result: string): Promise<ContactsPickerItem> {
let json: Array<any> = JSON.parse(result)
Utils.parseAsyncResults(json)
json = json[0] || {}
let orig: string = json[android.provider.ContactsContract.PhoneLookupColumns.NUMBER]
let sendi: ContactsPickerItem = {
contact_id: json[android.provider.ContactsContract.ContactsColumns.LOOKUP_KEY],
name: json[android.provider.ContactsContract.ContactsColumns.DISPLAY_NAME],
image: Utils.parseContactPhoto(json[android.provider.ContactsContract.ContactsColumns.PHOTO_THUMBNAIL_URI]),
phones: [{
label: Utils.parsePhoneType(json[android.provider.ContactsContract.PhoneLookupColumns.TYPE]),
phone: Utils.parseXid(orig),
}]
}
if (Utils.isXid(sendi.phones[0].phone)) {
return Promise.resolve(sendi)
}
return Utils.fixXid(orig).then(function(fixed: string) {
sendi.phones[0].phone = fixed
return Promise.resolve(sendi)
})
})
}
type EPPickerDelegateImplCallback = (contacts: NSArray<EPContact>, error: NSError) => void
class EPPickerDelegateImpl extends NSObject implements EPPickerDelegate {
public static ObjCProtocols = [EPPickerDelegate]
static new(): EPPickerDelegateImpl {
return <EPPickerDelegateImpl>super.new()
}
private _callback: EPPickerDelegateImplCallback
public initWithCallback(callback: EPPickerDelegateImplCallback): EPPickerDelegateImpl {
this._callback = callback
return this
}
epContactPickerDidSelectContact(picker: EPContactsPicker, contact: EPContact) {
this._callback(NSArray.arrayWithObject(contact), null)
}
epContactPickerDidSelectMultipleContacts(picker: EPContactsPicker, contacts: NSArray<EPContact>) {
this._callback(contacts, null)
}
epContactPickerDidCancel(picker: EPContactsPicker, error: NSError) {
this._callback(null, error)
}
epContactPickerDidContactFetchFailed(picker: EPContactsPicker, error: NSError) {
this._callback(null, error)
}
}
export function pickContacts(title: string = 'Pick Contact'): Promise<ContactsPickerItem> {
return new Promise(function(resolve, reject) {
let delegate: EPPickerDelegateImpl = EPPickerDelegateImpl.new()
.initWithCallback(function(contacts: NSArray<EPContact>, error: NSError) {
let app: UIApplication = application.ios.nativeApp
app.setStatusBarStyleAnimated(UIStatusBarStyle.LightContent, true)
delegate = null
if (error) {
return reject(error.description)
}
let sendi: Array<ContactsPickerItem> = []
let count: number = contacts.count - 1
contacts.enumerateObjectsUsingBlock(function block(epcontact: EPContact, index: number) {
let contact: CNContact = epcontact.valueForKey('originalCNContact')
let contact_id: string = contact.identifier
let name: string = contact.givenName + ' ' + contact.familyName
let phones: Array<ContactsPickerPhones> = []
let addresses: NSArray<CNLabeledValue<CNPhoneNumber>> = contact.phoneNumbers
let i: number, len: number = addresses.count
for (i = 0; i < len; i++) {
let item: CNLabeledValue<CNPhoneNumber> = addresses[i]
let phone: string = item.value.stringValue
let label: string = _.capitalize(CNLabeledValue.localizedStringForLabel(item.label))
phones.push({ phone, label })
}
let image: ImageSource = null
if (contact.imageDataAvailable) {
// image = fromNativeSource(UIImage.alloc().initWithData(contact.thumbnailImageData))
image = Utils.parseContactPhoto(contact.thumbnailImageData)
}
sendi.push({ contact_id, name, phones, image })
if (index == count) {
resolve(sendi)
}
})
})
let picker: EPContactsPicker = EPContactsPicker.alloc()
picker.initWithDelegateMultiSelectionContactsTitleSubtitleCellTypeFilterOnlyWithPhones(
delegate,
false,
title,
SubtitleCellValue.PhoneNumber,
true
)
let ctrl: UINavigationController = UINavigationController.new()
ctrl.initWithRootViewController(picker)
let root: UIViewController = topmost().currentPage.ios
root.presentViewControllerAnimatedCompletion(ctrl, true, function completion() {
let app: UIApplication = application.ios.nativeApp
app.setStatusBarStyleAnimated(UIStatusBarStyle.Default, true)
})
}).then(function(results: Array<ContactsPickerItem>) {
if (_.isEmpty(results)) {
return Promise.reject('isEmpty(results)')
}
let result: ContactsPickerItem = results[0]
let phones: Array<ContactsPickerPhones> = result.phones
if (phones.length == 1) {
return Promise.resolve(result)
}
let actions: Array<string> = []
let i: number, len: number = phones.length
for (i = 0; i < len; i++) {
let phone: ContactsPickerPhones = phones[i]
actions.push(phone.phone + ' - ' + phone.label)
}
return action({
title: 'Choose Phone Number',
cancelable: true,
cancelButtonText: 'Cancel',
actions,
}).then(function(reply: string) {
if (reply == 'Cancel') {
return Promise.reject('reply == Cancel')
}
let index: number = actions.findIndex(function(v) {
return v == reply
})
result.phones = [result.phones[index]]
return Promise.resolve(result)
})
}).then(function(result: ContactsPickerItem) {
let phone: string = result.phones[0].phone
let uname: string = Utils.parseXid(phone)
if (Utils.isXid(uname)) {
return Promise.resolve(result)
}
return Utils.fixXid(phone).then(function(fixed: string) {
result.phones[0].phone = fixed
return Promise.resolve(result)
})
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment