{$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:
Posts (Atom)