The mobile (iOS) application extension of the now deprecated Addressable Web App.
This repository houses Addressable's mobile iOS suite that permits Addressable users to:
- Build, track, edit, and send 'Radius' mailing campaigns
- Recieve push notificaitons related to mailing status (ie. recipient list curation, mailing status)
- Make and recieve related incoming lead calls and messages, along with handling any Twilio smart number telephoney related features
- Tag incoming leads (ie. Spam, Strong or Fair lead)
- Update user preferences (ie. change handwritng styles, top-up token count, invite teammates, edit address)
- Send feedback
See testing script for a breakdown of all application features.
- Xcode 13.0
- min iOS / device version: iOS 13.0 / iPhone 6s
- Install Git LFS
- Install Swift-lint
- Install audience-service for local recipient list curation
- Install illustrator-job-queue for mailing image preview creation
- Install Adobe Illustrator License Required
- Install the Latest version of Addressable API
git clone [email protected]:Addressable/looking_glass.git- Open Xcode click
File>Open>[your_path_to_looking_glass_repo]/Addressable.xcodeproj
- Set Targets to
Debug>iPhone_6s_or_above_simulator Cmd-Bto BuildCmd-Rto Run- Sign-In to App w/ Addressable Login Credentials
- Install oh-my-zsh to make terminal command line usage quick and easy
- Install Homebrew to make adding dependencies to your Mac easy
- Add the following to your
.Bash_Profileor.zshrc(Please take note of differing./PATHs):
###### Run inside of illustrator_job_queue ######
run_layout_engine() {
python layout_engine.py -e dev
}
###### Run inside of audience-service ######
run_datatree_searches() {
python main.py -e dev_ari
}
run_audience_service() {
~/addressable/audience_service && source venv/bin/activate
}
run_illustrator() {
~/addressable/illustrator_job_queue && source venv/bin/activate && cd python
}
sidekick() {
~/addressable/letters && Bundle exec sidekiq -C config/sidekiq.yml
}
run_addressable_app(){
~/addressable/letters && bundle install && bundle exec rails db:migrate RAILS_ENV=development && bundle exec rails s
}
run_ngrok() {
addressable/ngrok http -subdomain=addressabledev 3000
}
open_new_tab() {
osascript -e 'tell application "Terminal" to activate' \
-e 'tell application "System Events" to tell process "Terminal" to keystroke "t" using command down' \
-e 'tell application "Terminal" to do script "'$1'" in selected tab of the front window'
}
start_up_addressable() {
open_new_tab run_ngrok && open_new_tab run_addressable_app && sleep 2 && open_new_tab sidekick && sleep 2 && open_new_tab run_illustrator && sleep 2 && open_new_tab run_audience_service && open_new_tab ~/addressable/looking_glass && exit
}
- Run
start_up_addressable()in a new Terminal shell to immediately get a working local instance of the Addressable local API running: See Working Demo
-
As of this writing there is no "renewing" an Apple certificate, you must create a new one to replace the old one.
-
The steps are the same for renewing all Apple certificates (VOIP, Sandbox, Development, Distribution etc.)
-
You do * NOT * need to revoke or remove the original / expiring certificates. If you do, only do so after updating all third-party services with the new certificate.
1 - Login to the Apple Development Portal, navigate to the "Certificates, Identifiers & Profiles" page.
2 - Tap on the (+) icon.
3 - Select the Software or Service Certificate you desire to create.
4 - Select the related App ID you wish to associate with the certificate.
5 - Follow the steps to create a new certification request on your Mac.
6 - Upload the .certSigningRequest file that you just created.
7 - Click the download button to get the .cer file from Apple.
8 - Double-click the downloaded .cer file on your Mac to add it to your keychain.
9 - Find the newly added certificate in the Keychain Access Application window and right-click it to export as .p12 and create a secure password (store in 1password or some password manager).
10 - Use the newly created .p12 certificate to distribute to all third-party services and servers that'll require it for authorization.
1 - Go to Amazon's AWS SNS page, click on the "Push Notifications" tab to see the list of your Platform Applications.
2 - Select the application that needs renewed credentials.
3 - Select the Edit button.
4 - Select Certificate under the "Authentication Method" heading.
5 - Choose the .p12 file you created locally and provide the secure password.
6 - Save Changes.
1 - Go to Twilio's Mobile Push Credentials page.
2 - Select the application that needs renewed credentials.
3 - Keep this page open on your browser and open a new Terminal shell. We need to extract the certificate key and private key from the .p12.
4 - Enter the following command into your terminal to create the cert.pem: openssl pkcs12 -in [PATH_TO_YOUR_.p12] -nokeys -out cert.pem -nodes.
5 - Enter the following command into your terminal to create the key.pem: openssl pkcs12 -in [PATH_TO_YOUR_.p12] -nocerts -out key.pem -nodes.
6 - Run the following command into your terminal: openssl rsa -in key.pem -out key.pem.
7 - Run the following command into your terminal:
open -a TextEdit [PATH_TO_YOUR_cert.pem].
9 - Copy and paste everything within and including the -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- boundaries to Mobile Push Credentials page under Certificate.
10 - Run the following command in your terminal:
open -a TextEdit [PATH_TO_YOUR_key.pem].
11 - Copy and paste everything within and including the -----BEGIN RSA PRIVATE KEY----- and -----END RSA PRIVATE KEY----- boundaries to Mobile Push Credentials page under Private Key.
12 - Save Changes.
This application is developed using Apple's Swift / Swift UI Framework. The application is broken down into three environments, each connecting to the cooresponding Addressable API environment:
Release- API: https://live.addressable.app/api/v1Sandbox- API: https://sandbox.addressable.app/api/v1Debug :: Staging- API: http://localhost:3000/api/v1 :: http://ngork_tunnel/api/v1- For local physical device testing, especially when testing telephoney related features like phone calls it helps to use ngork to setup a web tunnel to your local running instance of the API.
The adopted design pattern is Model-View-ViewModel (MVVM) using the Combine framework to manage state. The idea being to separate the UI logic from the business logic in order to make apps easier to develop and test.
In short the design pattern helps to guide the relationships between three components: View, ViewModel, Model in the following way:
- The
Viewhas a reference to theViewModel, but not vice-versa. - The
ViewModelhas a reference to theModel, but not vice-versa. - The
Viewhas no reference to theModelor vice-versa.
General rules to follow when developing a new View in the application:
- Keep the
Viewlightweight; consisting only of UI / appearance related code (ie. text size, background color, spacing) - Place and name all View files in
Addressable/Views/[related_view_group]/[view_name]View - Place and name all ViewModel files in
Addressable/ViewModels/[view_name]ViewModel - Place all Model files in
Addressable/Models/[model_name]
This application follows the formating set by Swift-lint
To run linter and auto format your files run the following on your command line:
swiftlint autocorrect --format --path [PATH_TO_LOOKING_GLASS]/looking_glass/Addressable
- Name all varibles, classes, and files using
CamelCasestyle. - Use common sense with file placement (ie. util classes in
Utilesgroup, service classes inServicesgroup, core data models inCoreDataModelsgroup etc.). - Designate files sections using Xcode
// MARK: -denotation to make it easier for differentiate sections of a file.
The following are some of the TODO's where some code clean up and refactoring is required:
-
Addressable.swift:
class Applicationshould be renamed toAppDelegatewaiting on this Swift Lint Issue to get resolved.- Currently using deprecated
keyWindowto display permissions alert at initial application invocation. Should be removed when mobile app sign up flow is designed and decided on. currentViewandselectMailingapplication level varibles should be revisited when Sphere and Farming Mailings are added to the app.
-
ComposeRadiusTopicSelectionView.swift & MessageTemplateSelectionView.swift:
- These files need to be broken down into simple reusable view components for
Multi-Touch Topic Selection,Message Template Selection, andMerge Tag Variablehandling. SeeMailingRecipientViewandMailingDetailViewas potential examples to go off of.
- These files need to be broken down into simple reusable view components for
-
MailingDetialView.swift & ComposeRadiusView.swift: :
- The data flow of these files should probably be revisited.
TBD
.
|____ViewModels
| |____ConfirmAndSendMailingViewModel.swift
| |____ComposeRadiusViewModel.swift
| |____CallsViewModel.swift
| |____SelectAudienceViewModel.swift
| |____PreviewViewModel.swift
| |____EditReturnAddressViewModel.swift
| |____MailingDetailViewModel.swift
| |____MessageTemplateSelectionViewModel.swift
| |____MessagesViewModel.swift
| |____TagIncomingLeadViewModel.swift
| |____SendFeedbackViewModel.swift
| |____MailingCoverImagePagerViewModel.swift
| |____DashboardViewModel.swift
| |____CampaignsViewModel.swift
| |____MailingCoverImageGalleryViewModel.swift
| |____SignInViewModel.swift
| |____MailingRecipientsListViewModel.swift
| |____ProfileViewModel.swift
|____Campaigns.xcdatamodeld
| |____Campaigns.xcdatamodel
| | |____contents
|____AnalyticEvents.xcdatamodeld
| |____AnalyticEvents.xcdatamodel
| | |____contents
|____.DS_Store
|____Assests.xcassets
| |____Contents.json
| |____AddressableAssests.imageset
| | |____Contents.json
| | |____iu.png
|____User.xcdatamodeld
| |____User.xcdatamodel
|____AddressableApp.swift
|____Assets.xcassets
| |____.DS_Store
| |____BlankCard.imageset
| | |____card.png
| | |____Contents.json
| |____EyeOpen.imageset
| | |____EyeOpen.png
| | |____Contents.json
| |____EyeClose.imageset
| | |____Contents.json
| | |____EyeClose.png
| |____AppIcon.appiconset
| | |[email protected]
| | |[email protected]
| | |[email protected]
| | |[email protected]
| | |[email protected]
| | |[email protected]
| | |[email protected]
| | |[email protected]
| | |[email protected]
| | |[email protected]
| | |____Contents.json
| | |[email protected]
| | |[email protected]
| | |[email protected]
| | |[email protected]
| | |[email protected]
| | |[email protected]
| | |[email protected]
| | |[email protected]
| | |[email protected]
| |____AccentColor.colorset
| | |____Contents.json
| |____StyleSamples.imageset
| | |____style_samples.png
| | |____Contents.json
| |____AppIcon-Dev.appiconset
| | |[email protected]
| | |[email protected]
| | |[email protected]
| | |[email protected]
| | |[email protected]
| | |[email protected]
| | |____1024x1024.png
| | |[email protected]
| | |[email protected]
| | |____Contents.json
| | |[email protected]
| |____ZippyIcon.imageset
| | |____50ca91aa-7cd6-4df5-8e3b-2ab6486db33f.png
| | |____Contents.json
| |____Contents.json
|____Models
| |____Analytics.swift
| |____Authorization.swift
| |____MessageTemplate.swift
| |____CallManager.swift
| |____Handwriting.swift
| |____.DS_Store
| |____DataTreeSearch.swift
| |____MailingCoverImage.swift
| |____PersistentContainer.swift
| |____Recipient.swift
| |____Message.swift
| |____IncomingLead.swift
| |____CustomNote.swift
| |____MultiTouchTopic.swift
| |____Mailing.swift
| |____CoreDataModels
| | |____AnalyticEvent+CoreDataProperties.swift
| | |____PersistedCampaign+CoreDataClass.swift
| | |____AnalyticEvent+CoreDataClass.swift
| | |____PersistedCampaign +CoreDataProperties.swift
| |____Account.swift
| |____Feedback.swift
|____Preview Content
| |____Preview Assets.xcassets
| | |____Contents.json
|____Mailings.xcdatamodeld
| |____Mailings.xcdatamodel
|____Utilities
| |____NumberUtils.swift
| |____EnumUtil.swift
| |____JsonUtil.swift
| |____DateUtil.swift
| |____BordersUtils.swift
| |____KeychainServiceUtil.swift
| |____ColorsUtil.swift
| |____PermissionsUtil.swift
| |____FontUtils.swift
| |____AnalyticsTracker.swift
| |____DictionaryUtil.swift
| |____UIDeviceUtil.swift
| |____SliderUtils.swift
| |____UtilityProvider.swift
| |____ArrayUtil.swift
| |____StringsUtil.swift
|____Addressable.entitlements
|____Views
| |____DashboardView.swift
| |____ViewsUtilities
| | |____MultilineTextView.swift
| | |____SegmentedControlIconOptionView.swift
| | |____CloneMailingViewModel.swift
| | |____AddMenuItem.swift
| | |____MessageAlert.swift
| | |____PreviewView.swift
| | |____ListSeparatorStyle.swift
| | |____CustomHeader.swift
| | |____DetectScrollView.swift
| | |____AdaptsToKeyboard.swift
| | |____CheckView.swift
| | |____SliderView.swift
| | |____CustomSegmentedPickerView.swift
| | |____TextFieldModifier.swift
| | |____RefreshableScrollView.swift
| | |____Popup.swift
| |____AppView.swift
| |____RadiusMailingViews
| | |____ComposeRadiusSelectLocationView.swift
| | |____TargetCriteriaSliderView.swift
| | |____ComposeRadiusView.swift
| | |____ComposeRadiusTopicSelectionView.swift
| | |____TargetCriteriaMenuView.swift
| | |____ComposeRadiusConfirmSendView.swift
| | |____ComposeRadiusListConfirmationView.swift
| | |____ComposeRadiusCoverImageSelectionView.swift
| | |____GoogleMapsView.swift
| | |____ComposeRadiusAudienceConfirmationView.swift
| |____MailingRecipientsListView.swift
| |____CallViews
| | |____AddressableCallView.swift
| | |____KeyPadView.swift
| | |____CallListView.swift
| | |____TagIncomingLeadView.swift
| | |____CallListSectionHeaderView.swift
| |____ProfileSettingViews
| | |____ProfileView.swift
| | |____ProfileSettingSectionView.swift
| | |____EditUserAddressView.swift
| |____SignInView.swift
| |____DashboardViews
| | |____MailingCardItemView.swift
| | |____DashboardView.swift
| | |____CalendarTileView.swift
| | |____CampaignsFilterBoxesView.swift
| | |____NavigationMenuView.swift
| | |____CampaignSectionHeaderView.swift
| | |____SendFeedbackView.swift
| | |____CampaignsView.swift
| | |____CampaignsListView.swift
| | |____MessageTemplateSelectionView.swift
| |____MailingCoverArtView.swift
| |____MessageViews
| | |____MessageListView.swift
| | |____ContentMessageView.swift
| | |____MessageChatView.swift
| | |____MessageView.swift
| |____MailingDetailViews
| | |____MailingImagePreviewView.swift
| | |____CloneMailingView.swift
| | |____ConfirmAndSendMailingView.swift
| | |____EditReturnAddressView.swift
| | |____SelectAudienceView.swift
| | |____MailingCoverImagePagerView.swift
| | |____MailingDetailView.swift
| | |____MailingCoverImageGalleryView.swift
|____Info.plist
|____Services
| |____CallService.swift
| |____ApiService.swift
| |____DependencyProvider.swift
| |____ServiceProvider.swift
Contributors
- 0.1.5
- Various bug fixes and optimizations
- See commit change
- 0.1.4
- Various bug fixes and optimizations
- See commit change
- 0.1.3
- Various bug fixes and optimizations
- See commit change
- 0.1.2
- Various bug fixes and optimizations
- See commit change
- 0.1.1
- Various bug fixes and optimizations
- See commit change
- 0.0.2
- Various bug fixes and optimizations
- See commit change
- 0.0.1
- Various bug fixes and optimizations
- See commit change
- 0.0.0
- Initial Release
©2021 Addressablemail.com


