{$ifc not TARGET_OS_IPHONE}
// Parameters for all Panner AudioUnits
const
// Global, Linear, 0->1, 1
kPannerParam_Gain = 0;
// Global, Degrees, -180->180, 0
kPannerParam_Azimuth = 1;
// Global, Degrees, -90->90, 0
kPannerParam_Elevation = 2;
// Global, Linear, 0->1, 1
kPannerParam_Distance = 3; // 0 .. 1
// Global, Meters, 0.01->1000, 1
kPannerParam_CoordScale = 4;
// Global, Meters, 0.01->1000, 1
kPannerParam_RefDistance = 5;
{$endc} {not TARGET_OS_IPHONE}
// Parameters for the AUMixer3D unit
const
// Input, Degrees, -180->180, 0
k3DMixerParam_Azimuth = 0;
// Input, Degrees, -90->90, 0
k3DMixerParam_Elevation = 1;
// Input, Metres, 0->10000, 0
k3DMixerParam_Distance = 2;
// Input/Output, dB, -120->20, 0
k3DMixerParam_Gain = 3;
// Input, rate scaler 0.5 -> 2.0
k3DMixerParam_PlaybackRate = 4;
{$ifc not TARGET_OS_IPHONE}
// Desktop specific 3D mixer parameters
// Input, Dry/Wet equal-power blend, % 0.0 -> 100.0
k3DMixerParam_ReverbBlend = 5;
// Global, dB, -40.0 -> +40.0
k3DMixerParam_GlobalReverbGain = 6;
// Input, Lowpass filter attenuation at 5KHz : decibels -100.0dB -> 0.0dB
// smaller values make both direct and reverb sound more muffled; a value of 0.0 indicates no filtering
// Occlusion is a filter applied to the sound prior to the reverb send
k3DMixerParam_OcclusionAttenuation = 7;
// Input, Lowpass filter attenuation at 5KHz : decibels -100.0dB -> 0.0dB
// smaller values make direct sound more muffled; a value of 0.0 indicates no filtering
// Obstruction is a filter applied to the "direct" part of the sound (so is post reverb send)
k3DMixerParam_ObstructionAttenuation = 8;
// Input/Output, dB, -120->20, 0
k3DMixerParam_MinGain = 9;
// Input/Output, dB, -120->20, 0
k3DMixerParam_MaxGain = 10;
// read-only
//
// For each of the following, use the parameter ID plus the channel number
// to get the specific parameter ID for a given channel.
// For example, k3DMixerParam_PostAveragePower indicates the left channel
// while k3DMixerParam_PostAveragePower + 1 indicates the right channel.
k3DMixerParam_PreAveragePower = 1000;
k3DMixerParam_PrePeakHoldLevel = 2000;
k3DMixerParam_PostAveragePower = 3000;
k3DMixerParam_PostPeakHoldLevel = 4000;
{$endc} { not TARGET_OS_IPHONE }
// Parameters for the AUMultiChannelMixer unit
const
// Global, Linear Gain, 0->1, 1
kMultiChannelMixerParam_Volume = 0;
// Global, Boolean, 0->1, 1
kMultiChannelMixerParam_Enable = 1;
// Global, Pan
kMultiChannelMixerParam_Pan = 2; // -1 - 0 - 1, only valid when output is not mono
// relationship to mix matrix: last one in wins
// read-only
// these report level in dB, as do the other mixers
kMultiChannelMixerParam_PreAveragePower = 1000;
kMultiChannelMixerParam_PrePeakHoldLevel = 2000;
kMultiChannelMixerParam_PostAveragePower = 3000;
kMultiChannelMixerParam_PostPeakHoldLevel = 4000;
// Music Device
// Parameters for the AUSampler unit
const
// Global, dB, -90->12, 0
kAUSamplerParam_Gain = 900;
// Global, Semitones, -24->24, 0
kAUSamplerParam_CoarseTuning = 901;
// Global, Cents, -99->99, 0
kAUSamplerParam_FineTuning = 902;
// Global, -1.0->1.0, 0
kAUSamplerParam_Pan = 903;
// Output Units
// Parameters for the AudioDeviceOutput, DefaultOutputUnit, and SystemOutputUnit units
const
// Global, LinearGain, 0->1, 1
kHALOutputParam_Volume = 14;
// Parameters for the AUTimePitch, AUTimePitch (offline), AUPitch units
const
kTimePitchParam_Rate = 0;
kTimePitchParam_Pitch = 1;
kTimePitchParam_EffectBlend = 2; // only for the AUPitch unit
// Parameters for AUNewTimePitch
const
// Global, rate, 1/32 -> 32.0, 1.0
kNewTimePitchParam_Rate = 0;
// Global, Cents, -2400 -> 2400, 1.0
kNewTimePitchParam_Pitch = 1;
// Global, generic, 3.0 -> 32.0, 8.0
kNewTimePitchParam_Overlap = 4;
// Global, Boolean, 0->1, 1
kNewTimePitchParam_EnablePeakLocking = 6;
// Effect units
// Parameters for the AUBandpass unit
const
// Global, Hz, 20->(SampleRate/2), 5000
kBandpassParam_CenterFrequency = 0;
// Global, Cents, 100->12000, 600
kBandpassParam_Bandwidth = 1;
// Parameters for the AUHipass unit
const
// Global, Hz, 10->(SampleRate/2), 6900
kHipassParam_CutoffFrequency = 0;
// Global, dB, -20->40, 0
kHipassParam_Resonance = 1;
// Parameters for the AULowpass unit
const
// Global, Hz, 10->(SampleRate/2), 6900
kLowPassParam_CutoffFrequency = 0;
// Global, dB, -20->40, 0
kLowPassParam_Resonance = 1;
// Parameters for the AUHighShelfFilter unit
const
// Global, Hz, 10000->(SampleRate/2), 10000
kHighShelfParam_CutOffFrequency = 0;
// Global, dB, -40->40, 0
kHighShelfParam_Gain = 1;
// Parameters for the AULowShelfFilter unit
const
// Global, Hz, 10->200, 80
kAULowShelfParam_CutoffFrequency = 0;
// Global, dB, -40->40, 0
kAULowShelfParam_Gain = 1;
// Parameters for the AUParametricEQ unit
const
// Global, Hz, 20->(SampleRate/2), 2000
kParametricEQParam_CenterFreq = 0;
// Global, Hz, 0.1->20, 1.0
kParametricEQParam_Q = 1;
// Global, dB, -20->20, 0
kParametricEQParam_Gain = 2;
// Parameters for the AUPeakLimiter unit
const
// Global, Secs, 0.001->0.03, 0.012
kLimiterParam_AttackTime = 0;
// Global, Secs, 0.001->0.06, 0.024
kLimiterParam_DecayTime = 1;
// Global, dB, -40->40, 0
kLimiterParam_PreGain = 2;
// Parameters for the AUDynamicsProcessor unit
const
// Global, dB, -40->20, -20
kDynamicsProcessorParam_Threshold = 0;
// Global, dB, 0.1->40.0, 5
kDynamicsProcessorParam_HeadRoom = 1;
// Global, rate, 1->50.0, 2
kDynamicsProcessorParam_ExpansionRatio = 2;
// Global, dB
kDynamicsProcessorParam_ExpansionThreshold = 3;
// Global, secs, 0.0001->0.2, 0.001
kDynamicsProcessorParam_AttackTime = 4;
// Global, secs, 0.01->3, 0.05
kDynamicsProcessorParam_ReleaseTime = 5;
// Global, dB, -40->40, 0
kDynamicsProcessorParam_MasterGain = 6;
// Global, dB, read-only parameter
kDynamicsProcessorParam_CompressionAmount = 1000;
kDynamicsProcessorParam_InputAmplitude = 2000;
kDynamicsProcessorParam_OutputAmplitude = 3000;
// Parameters for the AUVarispeed unit
const
// Global, Rate, 0.25 -> 4.0, 1.0
kVarispeedParam_PlaybackRate = 0;
// Global, Cents, -2400 -> 2400, 0.0
kVarispeedParam_PlaybackCents = 1;
// Parameters for the Distortion unit
const
// Global, Milliseconds, 0.1 -> 500, 0.1
kDistortionParam_Delay = 0;
// Global, Rate, 0.1 -> 50, 1.0
kDistortionParam_Decay = 1;
// Global, Percent, 0 -> 100, 50
kDistortionParam_DelayMix = 2;
// Global, Percent, 0 -> 100
kDistortionParam_Decimation = 3;
// Global, Percent, 0 -> 100, 0
kDistortionParam_Rounding = 4;
// Global, Percent, 0 -> 100, 50
kDistortionParam_DecimationMix = 5;
// Global, Linear Gain, 0 -> 1, 1
kDistortionParam_LinearTerm = 6;
// Global, Linear Gain, 0 -> 20, 0
kDistortionParam_SquaredTerm = 7;
// Global, Linear Gain, 0 -> 20, 0
kDistortionParam_CubicTerm = 8;
// Global, Percent, 0 -> 100, 50
kDistortionParam_PolynomialMix = 9;
// Global, Hertz, 0.5 -> 8000, 100
kDistortionParam_RingModFreq1 = 10;
// Global, Hertz, 0.5 -> 8000, 100
kDistortionParam_RingModFreq2 = 11;
// Global, Percent, 0 -> 100, 50
kDistortionParam_RingModBalance = 12;
// Global, Percent, 0 -> 100, 0
kDistortionParam_RingModMix = 13;
// Global, dB, -80 -> 20, -6
kDistortionParam_SoftClipGain = 14;
// Global, Percent, 0 -> 100, 50
kDistortionParam_FinalMix = 15;
// Some parameters for the AUGraphicEQ unit
const
// Global, Indexed, currently either 10 or 31
kGraphicEQParam_NumberOfBands = 10000;
// Parameters for the AUMatrixReverb unit
const
// Global, EqPow CrossFade, 0->100, 100
kReverbParam_DryWetMix = 0;
// Global, EqPow CrossFade, 0->100, 50
kReverbParam_SmallLargeMix = 1;
// Global, Secs, 0.005->0.020, 0.06
kReverbParam_SmallSize = 2;
// Global, Secs, 0.4->10.0, 3.07
kReverbParam_LargeSize = 3;
// Global, Secs, 0.001->0.03, 0.025
kReverbParam_PreDelay = 4;
// Global, Secs, 0.001->0.1, 0.035
kReverbParam_LargeDelay = 5;
// Global, Genr, 0->1, 0.28
kReverbParam_SmallDensity = 6;
// Global, Genr, 0->1, 0.82
kReverbParam_LargeDensity = 7;
// Global, Genr, 0->1, 0.3
kReverbParam_LargeDelayRange = 8;
// Global, Genr, 0.1->1, 0.96
kReverbParam_SmallBrightness = 9;
// Global, Genr, 0.1->1, 0.49
kReverbParam_LargeBrightness = 10;
// Global, Genr, 0->1 0.5
kReverbParam_SmallDelayRange = 11;
// Global, Hz, 0.001->2.0, 1.0
kReverbParam_ModulationRate = 12;
// Global, Genr, 0.0 -> 1.0, 0.2
kReverbParam_ModulationDepth = 13;
// Global, Hertz, 10.0 -> 20000.0, 800.0
kReverbParam_FilterFrequency = 14;
// Global, Octaves, 0.05 -> 4.0, 3.0
kReverbParam_FilterBandwidth = 15;
// Global, Decibels, -18.0 -> +18.0, 0.0
kReverbParam_FilterGain = 16;
// Parameters for the AUDelay unit
const
// Global, EqPow Crossfade, 0->100, 50
kDelayParam_WetDryMix = 0;
// Global, Secs, 0->2, 1
kDelayParam_DelayTime = 1;
// Global, Percent, -100->100, 50
kDelayParam_Feedback = 2;
// Global, Hz, 10->(SampleRate/2), 15000
kDelayParam_LopassCutoff = 3;
// Parameters for the AUMultibandCompressor unit
const
// Global, dB, -40 -> 40, 0
kMultibandCompressorParam_Pregain = 0;
// Global, dB, -40 -> 40, 0
kMultibandCompressorParam_Postgain = 1;
// Global, Hertz, 20 -> (SampleRate/2), 120.0
kMultibandCompressorParam_Crossover1 = 2;
// Global, Hertz, 20 -> (SampleRate/2), 700.0
kMultibandCompressorParam_Crossover2 = 3;
// Global, Hertz, 20 -> (SampleRate/2), 3000.0
kMultibandCompressorParam_Crossover3 = 4;
// Global, dB, -100.0 -> 0.0, -22.0
kMultibandCompressorParam_Threshold1 = 5;
// Global, dB, -100.0 -> 0.0, -32.0
kMultibandCompressorParam_Threshold2 = 6;
// Global, dB, -100.0 -> 0.0, -33.0
kMultibandCompressorParam_Threshold3 = 7;
// Global, dB, -100.0 -> 0.0, -36.0
kMultibandCompressorParam_Threshold4 = 8;
// Global, dB, 0.1 -> 40.0, 5.0
kMultibandCompressorParam_Headroom1 = 9;
// Global, dB, 0.1 -> 40.0, 12.0
kMultibandCompressorParam_Headroom2 = 10;
// Global, dB, 0.1 -> 40.0, 5.0
kMultibandCompressorParam_Headroom3 = 11;
// Global, dB, 0.1 -> 40.0, 7.5
kMultibandCompressorParam_Headroom4 = 12;
// Global, Secs, 0.001 -> 0.200, 0.080
kMultibandCompressorParam_AttackTime = 13;
// Global, Secs, 0.010 -> 3.0, 0.120
kMultibandCompressorParam_ReleaseTime = 14;
// Global, dB, -20 -> 20, 0
kMultibandCompressorParam_EQ1 = 15;
// Global, dB, -20 -> 20, 0
kMultibandCompressorParam_EQ2 = 16;
// Global, dB, -20 -> 20, 0
kMultibandCompressorParam_EQ3 = 17;
// Global, dB, -20 -> 20, 0
kMultibandCompressorParam_EQ4 = 18;
// read-only parameters
// Global, dB, 0 -> 20
kMultibandCompressorParam_CompressionAmount1 = 1000;
// Global, dB, 0 -> 20
kMultibandCompressorParam_CompressionAmount2 = 2000;
// Global, dB, 0 -> 20
kMultibandCompressorParam_CompressionAmount3 = 3000;
// Global, dB, 0 -> 20
kMultibandCompressorParam_CompressionAmount4 = 4000;
// Global, dB, -120 -> 20
kMultibandCompressorParam_InputAmplitude1 = 5000;
// Global, dB, -120 -> 20
kMultibandCompressorParam_InputAmplitude2 = 6000;
// Global, dB, -120 -> 20
kMultibandCompressorParam_InputAmplitude3 = 7000;
// Global, dB, -120 -> 20
kMultibandCompressorParam_InputAmplitude4 = 8000;
// Global, dB, -120 -> 20
kMultibandCompressorParam_OutputAmplitude1 = 9000;
// Global, dB, -120 -> 20
kMultibandCompressorParam_OutputAmplitude2 = 10000;
// Global, dB, -120 -> 20
kMultibandCompressorParam_OutputAmplitude3 = 11000;
// Global, dB, -120 -> 20
kMultibandCompressorParam_OutputAmplitude4 = 12000;
// Parameters for the AUFilter unit
const
// Global, indexed, 0 -> 1, 0
kMultibandFilter_LowFilterType = 0;
// Global, Hertz, 10 -> (SampleRate/2), 100
kMultibandFilter_LowFrequency = 1;
// Global, dB, -18 -> +18, 0
kMultibandFilter_LowGain = 2;
// Global, Hertz, 10 -> (SampleRate/2), 100
kMultibandFilter_CenterFreq1 = 3;
// Global, dB, -18 -> +18, 0
kMultibandFilter_CenterGain1 = 4;
// Global, Octaves, 0.05 -> 3.0, 2.0
kMultibandFilter_Bandwidth1 = 5;
// Global, Hertz, 10 -> (SampleRate/2), 100
kMultibandFilter_CenterFreq2 = 6;
// Global, dB, -18 -> +18, 0
kMultibandFilter_CenterGain2 = 7;
// Global, Octaves, 0.05 -> 3.0, 2.0
kMultibandFilter_Bandwidth2 = 8;
// Global, Hertz, 10 -> (SampleRate/2), 100
kMultibandFilter_CenterFreq3 = 9;
// Global, dB, -18 -> +18, 0
kMultibandFilter_CenterGain3 = 10;
// Global, Octaves, 0.05 -> 3.0, 2.0
kMultibandFilter_Bandwidth3 = 11;
// Global, indexed, 0 -> 1, 0
kMultibandFilter_HighFilterType = 12;
// Global, Hertz, 10 -> (SampleRate/2), 100
kMultibandFilter_HighFrequency = 13;
// Global, dB, -18 -> +18, 0
kMultibandFilter_HighGain = 14;
// Mixer Units
// Parameters for the Stereo Mixer unit
const
// Input/Output, Mixer Fader Curve, 0->1, 1
kStereoMixerParam_Volume = 0;
// Input, Pan, 0->1, 0.5
kStereoMixerParam_Pan = 1;
// read-only
//
// For each of the following, use the parameter ID for the left channel
// and the parameter ID plus one for the right channel.
// For example, kStereoMixerParam_PostAveragePower indicates the left channel
// while kStereiMixerParam_PostAveragePower + 1 indicates the right channel.
kStereoMixerParam_PreAveragePower = 1000;
kStereoMixerParam_PrePeakHoldLevel = 2000;
kStereoMixerParam_PostAveragePower = 3000;
kStereoMixerParam_PostPeakHoldLevel = 4000;
// Parameters for the AUMatrixMixer unit
const
kMatrixMixerParam_Volume = 0;
kMatrixMixerParam_Enable = 1;
// read-only
// these report level in dB, as do the other mixers
kMatrixMixerParam_PreAveragePower = 1000;
kMatrixMixerParam_PrePeakHoldLevel = 2000;
kMatrixMixerParam_PostAveragePower = 3000;
kMatrixMixerParam_PostPeakHoldLevel = 4000;
// these report linear levels - for "expert" use only.
kMatrixMixerParam_PreAveragePowerLinear = 5000;
kMatrixMixerParam_PrePeakHoldLevelLinear = 6000;
kMatrixMixerParam_PostAveragePowerLinear = 7000;
kMatrixMixerParam_PostPeakHoldLevelLinear = 8000;
// Parameters for the AUNetReceive unit
const
// Global, indexed, 0 -> 5, read only
kAUNetReceiveParam_Status = 0;
kAUNetReceiveParam_NumParameters = 1;
// Parameters for the AUNetSend unit
const
// Global, indexed, 0 -> 5, read only
kAUNetSendParam_Status = 0;
kAUNetSendParam_NumParameters = 1;
// Status values for the AUNetSend and AUNetReceive units
const
kAUNetStatus_NotConnected = 0;
kAUNetStatus_Connected = 1;
kAUNetStatus_Overflow = 2;
kAUNetStatus_Underflow = 3;
kAUNetStatus_Connecting = 4;
kAUNetStatus_Listening = 5;
// Parameters for AURogerBeep
const
// Global, dB, -80 -> 0, -6
kRogerBeepParam_InGateThreshold = 0;
// Global, Milliseconds, 0 -> 1000, 1000
kRogerBeepParam_InGateThresholdTime = 1;
// Global, dB, -80 -> 0, -6
kRogerBeepParam_OutGateThreshold = 2;
// Global, Milliseconds, 0 -> 1000, 1000
kRogerBeepParam_OutGateThresholdTime = 3;
// Global, indexed, 0 -> 2, 2
kRogerBeepParam_Sensitivity = 4;
// Global, indexed, 0 -> 2, 0
kRogerBeepParam_RogerType = 5;
// Global, dB, -80 -> 20, -6
kRogerBeepParam_RogerGain = 6;
const
// Global, Cents, -1200, 1200, 0
kMusicDeviceParam_Tuning = 0;
// Global, dB, -120->40, 0
kMusicDeviceParam_Volume = 1;
// Global, dB, -120->40, 0
kMusicDeviceParam_ReverbVolume = 2;
const
// Global, indexed : AAC, AAC HE, AAC HEv2, AAC ELD
kRoundTripAACParam_Format = 0;
// Global, indexed
kRoundTripAACParam_EncodingStrategy = 1;
// Global, indexed
kRoundTripAACParam_RateOrQuality = 2;
// These are deprecated:
kRoundTripAACParam_BitRate = 1;
kRoundTripAACParam_Quality = 2;
kRoundTripAACParam_CompressedFormatSampleRate = 3;
Wikipedia
Search results
25 March 2014
Audio Units constants
16 March 2014
Inaugural Pasadena Civic Hackathon, and I was there
It was the very first civic hackathon at Pasadena, and they wanted to innovate means to utilize technology in society. The city has a profound and fantastic API anyone can readily use to make some awesome apps (http://data.cityofpasadena.net/home/).
So for the event, I entered with the goal to utilize and practice APNS, since I had not previously. I'm not going to lie: APNS is like faith, and you don't know what's going on. Unlike faith, there are some more down to earth metrics that make APNS concrete, although, it may not seem that way from the beginning. At the heart of APNS is SSL, and at the heart of SSL are certificates.
The trick is this, now listen carefully, the settings on the provisioning profile must match the application exactly, and they are both critical to setting up the environment for APNS.
I utilized a nice piece of code written for Node.js (http://orderoo.wordpress.com/2012/03/01/apple-push-notifications-on-heroku-using-node-js-8/), and refactored it a bit.
The product was successful, and at the end, #hackforpasadena was a great event. If ever there's a trivia question "who was the second human in the history of Pasadena civic hackathons to present a project?" the answer is me 8]
So for the event, I entered with the goal to utilize and practice APNS, since I had not previously. I'm not going to lie: APNS is like faith, and you don't know what's going on. Unlike faith, there are some more down to earth metrics that make APNS concrete, although, it may not seem that way from the beginning. At the heart of APNS is SSL, and at the heart of SSL are certificates.
The trick is this, now listen carefully, the settings on the provisioning profile must match the application exactly, and they are both critical to setting up the environment for APNS.
I utilized a nice piece of code written for Node.js (http://orderoo.wordpress.com/2012/03/01/apple-push-notifications-on-heroku-using-node-js-8/), and refactored it a bit.
The product was successful, and at the end, #hackforpasadena was a great event. If ever there's a trivia question "who was the second human in the history of Pasadena civic hackathons to present a project?" the answer is me 8]
04 March 2014
OAuth primer for iOS
So tonight I had a nice discussion with a colleague about OAuth. We had a nice review on OAuth.. and the take home point (please correct below!) is that OAuth is a user authentication protocol. there is v1 and v2.. v2 differs in that you can make requests to the app with a token.
Nevertheless, you pass over the user authentication process over to the OAuth protocol, and leverage that the user can utilize their other account(s) at popular and common services.
So we proceeded to create a makeshift OAuth controller.
We will be accessing the user login with UIWebView, the endpoint for OAuth services generates HTML that allows the user to log in to the host's Users database. So let's declare our variables:
On loadView (yes, no storyboard or xib), let's go ahead and make everything, the page is a webView that loads the authorization endpoint of Meetup, and a token and key are required for this to work. Therefore, I previously created my account, and generated an application utilizing their console.
(void) goMeetup is a delegate method I call in my other view controller:
I'm utilizing a helper method to parse the response. I want the userId, and to make a request of that user with that value. Therefore, if the value exists, then I will request the details of that user:
Each service has a unique API and enpoints. There will be variations in the flow, and in the case of Social Framework and others there are abstracted convenience methods to reach the same goal. You can see, such as with the Google + API that utilizes OAuth2, that the process looks quite different from the previously demonstrated example. These abstractions that are available in the Frameworks will handle the presentation of the user login dialog, and the ability to make changes to the user's entry in the host User database:
Nevertheless, you pass over the user authentication process over to the OAuth protocol, and leverage that the user can utilize their other account(s) at popular and common services.
So we proceeded to create a makeshift OAuth controller.
We will be accessing the user login with UIWebView, the endpoint for OAuth services generates HTML that allows the user to log in to the host's Users database. So let's declare our variables:
@interface LoginViewController ()@property (strong, nonatomic) UIWebView* webView; @property (strong, nonatomic) NSNumber* userId; @end
On loadView (yes, no storyboard or xib), let's go ahead and make everything, the page is a webView that loads the authorization endpoint of Meetup, and a token and key are required for this to work. Therefore, I previously created my account, and generated an application utilizing their console.
- (void)loadView
{
[super loadView];
UIButton* exit = [UIButton buttonWithType:UIButtonTypeRoundedRect];
exit.backgroundColor = [UIColor clearColor];
[exit setTitle:@"X" forState:UIControlStateNormal];
[exit addTarget:self action:@selector(exit) forControlEvents:UIControlEventTouchUpInside];
exit.frame = CGRectMake(20, 20, 44, 44);
[self.view addSubview:exit];
_webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, self.view.bounds.size.height, self.view.bounds.size.width, self.view.bounds.size.height)];
_webView.delegate = self;
[self.view addSubview:_webView];
}
(void) goMeetup is a delegate method I call in my other view controller:
- (void)goMeetup
{
NSString* scope = [NSString stringWithFormat:@"https://secure.meetup.com/oauth2/authorize?client_id=%@&response_type=code&redirect_uri=%@", MEETUP_CLIENTID, @"http://www.filmproj.com"];
CGRect newRect = self.view.bounds;
[_webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:scope]]];
[UIView animateWithDuration:0.3f animations:^{
_webView.frame = newRect;
}];
}
I'm utilizing a helper method to parse the response. I want the userId, and to make a request of that user with that value. Therefore, if the value exists, then I will request the details of that user:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
NSLog(@"request url lastpathComponent = %@", request.URL.lastPathComponent);
NSString *html = [webView stringByEvaluatingJavaScriptFromString:
@"document.body.innerHTML"];
NSString* part = [self scanString:html startTag:@"MM.Member={" endTag:@"\
"];
NSString* anId = [self scanString:part startTag:@"id:" endTag:@","];
NSNumberFormatter * f = [[NSNumberFormatter alloc] init];
[f setNumberStyle:NSNumberFormatterDecimalStyle];
self.userId = [f numberFromString:anId];
if (self.userId) {
[self userApi];
} else {
[self alertError];
}
return YES;
}
- (NSString *)scanString:(NSString *)string startTag:(NSString *)startTag endTag:(NSString *)endTag
{
NSString* scanString = @"";
if (string.length > 0) {
NSScanner* scanner = [[NSScanner alloc] initWithString:string];
[scanner scanUpToString:startTag intoString:nil];
scanner.scanLocation += [startTag length];
[scanner scanUpToString:endTag intoString:&scanString];
}
return scanString;
}
- (void)userApi
{
NSString* urlString = [NSString stringWithFormat:@"https://api.meetup.com/members?member_id=%@&key=%@", self.userId, MEETUP_KEY];
[NSURLConnection sendAsynchronousRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:urlString]] queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
if (data) {
NSDictionary* dictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
//NSLog(@"dictionary = %@", dictionary);
if (dictionary) {
NSDictionary* userResponse = [dictionary valueForKey:@"results"][0];
//NSLog(@"userResponse = %@", userResponse);
if (userResponse) {
NSString* city = [userResponse valueForKey:@"city"];
NSString* country = [userResponse valueForKey:@"country"];
NSString* name = [userResponse valueForKey:@"name"];
NSString* state = [userResponse valueForKey:@"state"];
NSString* avatarUrl = [userResponse valueForKey:@"photo_url"];
NSArray* topicsArray = [userResponse valueForKey:@"topics"];
NSMutableArray* topicsArrayHolder = [NSMutableArray array];
for (NSDictionary* json in topicsArray) {
NSLog(@"topicsArray = %@", topicsArray);
NSNumber* jsonId = [json valueForKey:@"id"];
NSString* jsonName = [json valueForKey:@"name"];
NSString* jsonUrlKey = [json valueForKey:@"urlKey"];
MeetupTopic* topic = [[MeetupTopic alloc] initWithTopicId:jsonId name:jsonName urlKey:jsonUrlKey];
[topicsArrayHolder addObject:topic];
}
[[UserAuthenticated sharedInstance] makeUserWithId:self.userId username:name city:city state:state country:country imageUrl:avatarUrl andTopics:topicsArrayHolder];
[topicsArrayHolder removeAllObjects];
// tests for user authenticated object
NSNumber* user0 = [[UserAuthenticated sharedInstance] userId];
NSString* user1 = [[UserAuthenticated sharedInstance] userName];
NSString* user2 = [[UserAuthenticated sharedInstance] city];
NSString* user3 = [[UserAuthenticated sharedInstance] state];
NSString* user4 = [[UserAuthenticated sharedInstance] country];
NSArray* user5 = [[UserAuthenticated sharedInstance] topicsArray];
UIImage* user6 = [[UserAuthenticated sharedInstance] avatar];
NSLog(@"%@\n%@\n%@\n%@\n%@\n%@\n%@", user0, user1, user2, user3, user4, user5, user6);
// dismiss controller
// update ui on other pages, and enable features
} else {
dispatch_async(dispatch_get_main_queue(), ^{
[self alertError];
});
}
} else {
dispatch_async(dispatch_get_main_queue(), ^{
[self alertError];
});
}
} else {
dispatch_async(dispatch_get_main_queue(), ^{
[self alertError];
});
}
}];
}
- (void)alertError
{
[[[UIAlertView alloc] initWithTitle:nil message:@"err, if it's not you it's me" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil] show];
}
@end
Each service has a unique API and enpoints. There will be variations in the flow, and in the case of Social Framework and others there are abstracted convenience methods to reach the same goal. You can see, such as with the Google + API that utilizes OAuth2, that the process looks quite different from the previously demonstrated example. These abstractions that are available in the Frameworks will handle the presentation of the user login dialog, and the ability to make changes to the user's entry in the host User database:
- (void)goGoogle
{
GPPSignIn *signIn = [GPPSignIn sharedInstance];
signIn.delegate = self;
signIn.shouldFetchGoogleUserEmail = YES;
signIn.clientID = GOOGLE_CLIENTID;
signIn.scopes = [NSArray arrayWithObjects:kGTLAuthScopePlusLogin,nil];
signIn.actions = [NSArray arrayWithObjects:@"http://schemas.google.com/ListenActivity",nil];
[signIn authenticate];
}
- (void)finishedWithAuth: (GTMOAuth2Authentication *)auth
error: (NSError *) error
{
NSLog(@"Received error %@ and auth object %@",error, auth);
NSString *urlStr = @"https://www.googleapis.com/oauth2/v1/userinfo?alt=json";
NSURL *url = [NSURL URLWithString:urlStr];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[auth authorizeRequest:request
completionHandler:^(NSError *error) {
NSString *output = nil;
if (error) {
output = [error description];
} else {
// Synchronous fetches like this are a really bad idea in Cocoa applications
//
// For a very easy async alternative, we could use GTMHTTPFetcher
NSURLResponse *response = nil;
NSData *data = [NSURLConnection sendSynchronousRequest:request
returningResponse:&response
error:&error];
if (data) {
// API fetch succeeded
output = [[NSString alloc] initWithData:data
encoding:NSUTF8StringEncoding];
}
NSLog(@"output:%@",output);
}
}];
}
Subscribe to:
Comments (Atom)