核心音频离线渲染GenericOutput

2024-06-13

有人使用 core-Audio 成功完成离线渲染吗?

我必须混合两个音频文件并应用混响(使用 2 AudioFilePlayer、MultiChannelMixer、Reverb2 和 RemoteIO)。 成功了。我可以在预览时保存它(在 RemoteIO 的 renderCallBack 上)。

我需要保存它而不播放它(离线)。 提前致谢。


离线渲染使用 GenericOutput AudioUnit 对我有用。 我在这里分享工作代码。 core-audio框架似乎有点。但其中的一些小事情,比如 ASBD、参数……等等,都会造成这些问题。努力吧,一定会成功的。不要放弃:-)。 core-audio 在处理低级音频时非常强大且有用。这就是我从过去几周学到的东西。享受:-D ....

在 .h 中声明这些

//AUGraph
AUGraph mGraph;
//Audio Unit References
AudioUnit mFilePlayer;
AudioUnit mFilePlayer2;
AudioUnit mReverb;
AudioUnit mTone;
AudioUnit mMixer;
AudioUnit mGIO;
//Audio File Location
AudioFileID inputFile;
AudioFileID inputFile2;
//Audio file refereces for saving
ExtAudioFileRef extAudioFile;
//Standard sample rate
Float64 graphSampleRate;
AudioStreamBasicDescription stereoStreamFormat864;

Float64 MaxSampleTime;

//在.m类中

- (id) init
{
    self = [super init];
    graphSampleRate = 44100.0;
    MaxSampleTime   = 0.0;
    UInt32 category = kAudioSessionCategory_MediaPlayback;
    CheckError(AudioSessionSetProperty(kAudioSessionProperty_AudioCategory,
                                   sizeof(category),
                                   &category),
           "Couldn't set category on audio session");
    [self initializeAUGraph];
    return self;
}

//ASBD设置

- (void) setupStereoStream864 {    
    // The AudioUnitSampleType data type is the recommended type for sample data in audio
    // units. This obtains the byte size of the type for use in filling in the ASBD.
    size_t bytesPerSample = sizeof (AudioUnitSampleType);
    // Fill the application audio format struct's fields to define a linear PCM,
    // stereo, noninterleaved stream at the hardware sample rate.
    stereoStreamFormat864.mFormatID          = kAudioFormatLinearPCM;
    stereoStreamFormat864.mFormatFlags       = kAudioFormatFlagsAudioUnitCanonical;
    stereoStreamFormat864.mBytesPerPacket    = bytesPerSample;
    stereoStreamFormat864.mFramesPerPacket   = 1;
    stereoStreamFormat864.mBytesPerFrame     = bytesPerSample;
    stereoStreamFormat864.mChannelsPerFrame  = 2; // 2 indicates stereo
    stereoStreamFormat864.mBitsPerChannel    = 8 * bytesPerSample;
    stereoStreamFormat864.mSampleRate        = graphSampleRate;
}

//AU图设置

- (void)initializeAUGraph
{
    [self setupStereoStream864];

    // Setup the AUGraph, add AUNodes, and make connections
// create a new AUGraph
CheckError(NewAUGraph(&mGraph),"Couldn't create new graph");

// AUNodes represent AudioUnits on the AUGraph and provide an
// easy means for connecting audioUnits together.
    AUNode filePlayerNode;
    AUNode filePlayerNode2;
AUNode mixerNode;
AUNode reverbNode;
AUNode toneNode;
AUNode gOutputNode;

// file player component
    AudioComponentDescription filePlayer_desc;
filePlayer_desc.componentType = kAudioUnitType_Generator;
filePlayer_desc.componentSubType = kAudioUnitSubType_AudioFilePlayer;
filePlayer_desc.componentFlags = 0;
filePlayer_desc.componentFlagsMask = 0;
filePlayer_desc.componentManufacturer = kAudioUnitManufacturer_Apple;

// file player component2
    AudioComponentDescription filePlayer2_desc;
filePlayer2_desc.componentType = kAudioUnitType_Generator;
filePlayer2_desc.componentSubType = kAudioUnitSubType_AudioFilePlayer;
filePlayer2_desc.componentFlags = 0;
filePlayer2_desc.componentFlagsMask = 0;
filePlayer2_desc.componentManufacturer = kAudioUnitManufacturer_Apple;

// Create AudioComponentDescriptions for the AUs we want in the graph
// mixer component
AudioComponentDescription mixer_desc;
mixer_desc.componentType = kAudioUnitType_Mixer;
mixer_desc.componentSubType = kAudioUnitSubType_MultiChannelMixer;
mixer_desc.componentFlags = 0;
mixer_desc.componentFlagsMask = 0;
mixer_desc.componentManufacturer = kAudioUnitManufacturer_Apple;

// Create AudioComponentDescriptions for the AUs we want in the graph
// Reverb component
AudioComponentDescription reverb_desc;
reverb_desc.componentType = kAudioUnitType_Effect;
reverb_desc.componentSubType = kAudioUnitSubType_Reverb2;
reverb_desc.componentFlags = 0;
reverb_desc.componentFlagsMask = 0;
reverb_desc.componentManufacturer = kAudioUnitManufacturer_Apple;


//tone component
    AudioComponentDescription tone_desc;
tone_desc.componentType = kAudioUnitType_FormatConverter;
//tone_desc.componentSubType = kAudioUnitSubType_NewTimePitch;
    tone_desc.componentSubType = kAudioUnitSubType_Varispeed;
tone_desc.componentFlags = 0;
tone_desc.componentFlagsMask = 0;
tone_desc.componentManufacturer = kAudioUnitManufacturer_Apple;


    AudioComponentDescription gOutput_desc;
gOutput_desc.componentType = kAudioUnitType_Output;
gOutput_desc.componentSubType = kAudioUnitSubType_GenericOutput;
gOutput_desc.componentFlags = 0;
gOutput_desc.componentFlagsMask = 0;
gOutput_desc.componentManufacturer = kAudioUnitManufacturer_Apple;

//Add nodes to graph

// Add nodes to the graph to hold our AudioUnits,
// You pass in a reference to the  AudioComponentDescription
// and get back an  AudioUnit
    AUGraphAddNode(mGraph, &filePlayer_desc, &filePlayerNode );
    AUGraphAddNode(mGraph, &filePlayer2_desc, &filePlayerNode2 );
    AUGraphAddNode(mGraph, &mixer_desc, &mixerNode );
    AUGraphAddNode(mGraph, &reverb_desc, &reverbNode );
    AUGraphAddNode(mGraph, &tone_desc, &toneNode );
AUGraphAddNode(mGraph, &gOutput_desc, &gOutputNode);


//Open the graph early, initialize late
// open the graph AudioUnits are open but not initialized (no resource allocation occurs here)

CheckError(AUGraphOpen(mGraph),"Couldn't Open the graph");

//Reference to Nodes
// get the reference to the AudioUnit object for the file player graph node
AUGraphNodeInfo(mGraph, filePlayerNode, NULL, &mFilePlayer);
AUGraphNodeInfo(mGraph, filePlayerNode2, NULL, &mFilePlayer2);
    AUGraphNodeInfo(mGraph, reverbNode, NULL, &mReverb);
    AUGraphNodeInfo(mGraph, toneNode, NULL, &mTone);
    AUGraphNodeInfo(mGraph, mixerNode, NULL, &mMixer);
AUGraphNodeInfo(mGraph, gOutputNode, NULL, &mGIO);

    AUGraphConnectNodeInput(mGraph, filePlayerNode, 0, reverbNode, 0);
    AUGraphConnectNodeInput(mGraph, reverbNode, 0, toneNode, 0);
    AUGraphConnectNodeInput(mGraph, toneNode, 0, mixerNode,0);
    AUGraphConnectNodeInput(mGraph, filePlayerNode2, 0, mixerNode, 1);
AUGraphConnectNodeInput(mGraph, mixerNode, 0, gOutputNode, 0);


    UInt32 busCount   = 2;    // bus count for mixer unit input

//Setup mixer unit bus count
    CheckError(AudioUnitSetProperty (
                                 mMixer,
                                 kAudioUnitProperty_ElementCount,
                                 kAudioUnitScope_Input,
                                 0,
                                 &busCount,
                                 sizeof (busCount)
                                 ),
           "Couldn't set mixer unit's bus count");

//Enable metering mode to view levels input and output levels of mixer
    UInt32 onValue = 1;
    CheckError(AudioUnitSetProperty(mMixer,
                                kAudioUnitProperty_MeteringMode,
                                kAudioUnitScope_Input,
                                0,
                                &onValue,
                                sizeof(onValue)),
           "error");

// Increase the maximum frames per slice allows the mixer unit to accommodate the
//    larger slice size used when the screen is locked.
    UInt32 maximumFramesPerSlice = 4096;

    CheckError(AudioUnitSetProperty (
                                 mMixer,
                                 kAudioUnitProperty_MaximumFramesPerSlice,
                                 kAudioUnitScope_Global,
                                 0,
                                 &maximumFramesPerSlice,
                                 sizeof (maximumFramesPerSlice)
                                 ),
           "Couldn't set mixer units maximum framers per slice");

// set the audio data format of tone Unit
    AudioUnitSetProperty(mTone,
                     kAudioUnitProperty_StreamFormat,
                     kAudioUnitScope_Global,
                     0,
                     &stereoStreamFormat864,
                     sizeof(AudioStreamBasicDescription));
// set the audio data format of reverb Unit
    AudioUnitSetProperty(mReverb,
                     kAudioUnitProperty_StreamFormat,
                     kAudioUnitScope_Global,
                     0,
                     &stereoStreamFormat864,
                     sizeof(AudioStreamBasicDescription));

// set initial reverb
    AudioUnitParameterValue reverbTime = 2.5;
    AudioUnitSetParameter(mReverb, 4, kAudioUnitScope_Global, 0, reverbTime, 0);
    AudioUnitSetParameter(mReverb, 5, kAudioUnitScope_Global, 0, reverbTime, 0);
    AudioUnitSetParameter(mReverb, 0, kAudioUnitScope_Global, 0, 0, 0);

    AudioStreamBasicDescription     auEffectStreamFormat;
    UInt32 asbdSize = sizeof (auEffectStreamFormat);
memset (&auEffectStreamFormat, 0, sizeof (auEffectStreamFormat ));

// get the audio data format from reverb
CheckError(AudioUnitGetProperty(mReverb,
                                kAudioUnitProperty_StreamFormat,
                                kAudioUnitScope_Input,
                                0,
                                &auEffectStreamFormat,
                                &asbdSize),
           "Couldn't get aueffectunit ASBD");


    auEffectStreamFormat.mSampleRate = graphSampleRate;

// set the audio data format of mixer Unit
    CheckError(AudioUnitSetProperty(mMixer,
                                kAudioUnitProperty_StreamFormat,
                                kAudioUnitScope_Output,
                                0,
                                &auEffectStreamFormat, sizeof(auEffectStreamFormat)),
           "Couldn't set ASBD on mixer output");

CheckError(AUGraphInitialize(mGraph),"Couldn't Initialize the graph");

    [self setUpAUFilePlayer];
    [self setUpAUFilePlayer2];  
}

//音频文件播放设置这里我是设置语音文件

-(OSStatus) setUpAUFilePlayer{
NSString *songPath = [[NSBundle mainBundle] pathForResource: @"testVoice" ofType:@".m4a"];
CFURLRef songURL = ( CFURLRef) [NSURL fileURLWithPath:songPath];

// open the input audio file
CheckError(AudioFileOpenURL(songURL, kAudioFileReadPermission, 0, &inputFile),
           "setUpAUFilePlayer AudioFileOpenURL failed");

AudioStreamBasicDescription fileASBD;
// get the audio data format from the file
UInt32 propSize = sizeof(fileASBD);
CheckError(AudioFileGetProperty(inputFile, kAudioFilePropertyDataFormat,
                                &propSize, &fileASBD),
           "setUpAUFilePlayer couldn't get file's data format");

// tell the file player unit to load the file we want to play
CheckError(AudioUnitSetProperty(mFilePlayer, kAudioUnitProperty_ScheduledFileIDs,
                                kAudioUnitScope_Global, 0, &inputFile, sizeof(inputFile)),
           "setUpAUFilePlayer AudioUnitSetProperty[kAudioUnitProperty_ScheduledFileIDs] failed");

UInt64 nPackets;
UInt32 propsize = sizeof(nPackets);
CheckError(AudioFileGetProperty(inputFile, kAudioFilePropertyAudioDataPacketCount,
                                &propsize, &nPackets),
           "setUpAUFilePlayer AudioFileGetProperty[kAudioFilePropertyAudioDataPacketCount] failed");

// tell the file player AU to play the entire file
ScheduledAudioFileRegion rgn;
memset (&rgn.mTimeStamp, 0, sizeof(rgn.mTimeStamp));
rgn.mTimeStamp.mFlags = kAudioTimeStampSampleTimeValid;
rgn.mTimeStamp.mSampleTime = 0;
rgn.mCompletionProc = NULL;
rgn.mCompletionProcUserData = NULL;
rgn.mAudioFile = inputFile;
rgn.mLoopCount = -1;
rgn.mStartFrame = 0;
rgn.mFramesToPlay = nPackets * fileASBD.mFramesPerPacket;

if (MaxSampleTime < rgn.mFramesToPlay)
{
    MaxSampleTime = rgn.mFramesToPlay;
}

CheckError(AudioUnitSetProperty(mFilePlayer, kAudioUnitProperty_ScheduledFileRegion,
                                kAudioUnitScope_Global, 0,&rgn, sizeof(rgn)),
           "setUpAUFilePlayer1 AudioUnitSetProperty[kAudioUnitProperty_ScheduledFileRegion] failed");

// prime the file player AU with default values
UInt32 defaultVal = 0;

CheckError(AudioUnitSetProperty(mFilePlayer, kAudioUnitProperty_ScheduledFilePrime,
                                kAudioUnitScope_Global, 0, &defaultVal, sizeof(defaultVal)),
           "setUpAUFilePlayer AudioUnitSetProperty[kAudioUnitProperty_ScheduledFilePrime] failed");


// tell the file player AU when to start playing (-1 sample time means next render cycle)
AudioTimeStamp startTime;
memset (&startTime, 0, sizeof(startTime));
startTime.mFlags = kAudioTimeStampSampleTimeValid;

startTime.mSampleTime = -1;
CheckError(AudioUnitSetProperty(mFilePlayer, kAudioUnitProperty_ScheduleStartTimeStamp,
                                kAudioUnitScope_Global, 0, &startTime, sizeof(startTime)),
           "setUpAUFilePlayer AudioUnitSetProperty[kAudioUnitProperty_ScheduleStartTimeStamp]");

return noErr;  
}

//音频文件播放设置这里我设置的是BGMusic文件

-(OSStatus) setUpAUFilePlayer2{
NSString *songPath = [[NSBundle mainBundle] pathForResource: @"BGmusic" ofType:@".mp3"];
CFURLRef songURL = ( CFURLRef) [NSURL fileURLWithPath:songPath];

// open the input audio file
CheckError(AudioFileOpenURL(songURL, kAudioFileReadPermission, 0, &inputFile2),
           "setUpAUFilePlayer2 AudioFileOpenURL failed");

AudioStreamBasicDescription fileASBD;
// get the audio data format from the file
UInt32 propSize = sizeof(fileASBD);
CheckError(AudioFileGetProperty(inputFile2, kAudioFilePropertyDataFormat,
                                &propSize, &fileASBD),
           "setUpAUFilePlayer2 couldn't get file's data format");

// tell the file player unit to load the file we want to play
CheckError(AudioUnitSetProperty(mFilePlayer2, kAudioUnitProperty_ScheduledFileIDs,
                                kAudioUnitScope_Global, 0, &inputFile2, sizeof(inputFile2)),
           "setUpAUFilePlayer2 AudioUnitSetProperty[kAudioUnitProperty_ScheduledFileIDs] failed");

UInt64 nPackets;
UInt32 propsize = sizeof(nPackets);
CheckError(AudioFileGetProperty(inputFile2, kAudioFilePropertyAudioDataPacketCount,
                                &propsize, &nPackets),
           "setUpAUFilePlayer2 AudioFileGetProperty[kAudioFilePropertyAudioDataPacketCount] failed");

// tell the file player AU to play the entire file
ScheduledAudioFileRegion rgn;
memset (&rgn.mTimeStamp, 0, sizeof(rgn.mTimeStamp));
rgn.mTimeStamp.mFlags = kAudioTimeStampSampleTimeValid;
rgn.mTimeStamp.mSampleTime = 0;
rgn.mCompletionProc = NULL;
rgn.mCompletionProcUserData = NULL;
rgn.mAudioFile = inputFile2;
rgn.mLoopCount = -1;
rgn.mStartFrame = 0;
rgn.mFramesToPlay = nPackets * fileASBD.mFramesPerPacket;


if (MaxSampleTime < rgn.mFramesToPlay)
{
    MaxSampleTime = rgn.mFramesToPlay;
}

CheckError(AudioUnitSetProperty(mFilePlayer2, kAudioUnitProperty_ScheduledFileRegion,
                                kAudioUnitScope_Global, 0,&rgn, sizeof(rgn)),
           "setUpAUFilePlayer2 AudioUnitSetProperty[kAudioUnitProperty_ScheduledFileRegion] failed");

// prime the file player AU with default values
UInt32 defaultVal = 0;
CheckError(AudioUnitSetProperty(mFilePlayer2, kAudioUnitProperty_ScheduledFilePrime,
                                kAudioUnitScope_Global, 0, &defaultVal, sizeof(defaultVal)),
           "setUpAUFilePlayer2 AudioUnitSetProperty[kAudioUnitProperty_ScheduledFilePrime] failed");


// tell the file player AU when to start playing (-1 sample time means next render cycle)
AudioTimeStamp startTime;
memset (&startTime, 0, sizeof(startTime));
startTime.mFlags = kAudioTimeStampSampleTimeValid;
startTime.mSampleTime = -1;
CheckError(AudioUnitSetProperty(mFilePlayer2, kAudioUnitProperty_ScheduleStartTimeStamp,
                                kAudioUnitScope_Global, 0, &startTime, sizeof(startTime)),
           "setUpAUFilePlayer2 AudioUnitSetProperty[kAudioUnitProperty_ScheduleStartTimeStamp]");

return noErr;  
}

//开始保存文件

- (void)startRecordingAAC{
AudioStreamBasicDescription destinationFormat;
memset(&destinationFormat, 0, sizeof(destinationFormat));
destinationFormat.mChannelsPerFrame = 2;
destinationFormat.mFormatID = kAudioFormatMPEG4AAC;
UInt32 size = sizeof(destinationFormat);
OSStatus result = AudioFormatGetProperty(kAudioFormatProperty_FormatInfo, 0, NULL, &size, &destinationFormat);
if(result) printf("AudioFormatGetProperty %ld \n", result);
NSArray  *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];



NSString *destinationFilePath = [[NSString alloc] initWithFormat: @"%@/output.m4a", documentsDirectory];
CFURLRef destinationURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
                                                        (CFStringRef)destinationFilePath,
                                                        kCFURLPOSIXPathStyle,
                                                        false);
[destinationFilePath release];

// specify codec Saving the output in .m4a format
result = ExtAudioFileCreateWithURL(destinationURL,
                                   kAudioFileM4AType,
                                   &destinationFormat,
                                   NULL,
                                   kAudioFileFlags_EraseFile,
                                   &extAudioFile);
if(result) printf("ExtAudioFileCreateWithURL %ld \n", result);
CFRelease(destinationURL);

// This is a very important part and easiest way to set the ASBD for the File with correct format.
AudioStreamBasicDescription clientFormat;
UInt32 fSize = sizeof (clientFormat);
memset(&clientFormat, 0, sizeof(clientFormat));
// get the audio data format from the Output Unit
CheckError(AudioUnitGetProperty(mGIO,
                                kAudioUnitProperty_StreamFormat,
                                kAudioUnitScope_Output,
                                0,
                                &clientFormat,
                                &fSize),"AudioUnitGetProperty on failed");

// set the audio data format of mixer Unit
CheckError(ExtAudioFileSetProperty(extAudioFile,
                                   kExtAudioFileProperty_ClientDataFormat,
                                   sizeof(clientFormat),
                                   &clientFormat),
           "ExtAudioFileSetProperty kExtAudioFileProperty_ClientDataFormat failed");
// specify codec
UInt32 codec = kAppleHardwareAudioCodecManufacturer;
CheckError(ExtAudioFileSetProperty(extAudioFile,
                                   kExtAudioFileProperty_CodecManufacturer,
                                   sizeof(codec),
                                   &codec),"ExtAudioFileSetProperty on extAudioFile Faild");

CheckError(ExtAudioFileWriteAsync(extAudioFile, 0, NULL),"ExtAudioFileWriteAsync Failed");

[self pullGenericOutput];
}

// 手动输入并从 GenericOutput 节点获取数据/缓冲区。

-(void)pullGenericOutput{
AudioUnitRenderActionFlags flags = 0;
AudioTimeStamp inTimeStamp;
memset(&inTimeStamp, 0, sizeof(AudioTimeStamp));
inTimeStamp.mFlags = kAudioTimeStampSampleTimeValid;
UInt32 busNumber = 0;
UInt32 numberFrames = 512;
inTimeStamp.mSampleTime = 0;
int channelCount = 2;

NSLog(@"Final numberFrames :%li",numberFrames);
int totFrms = MaxSampleTime;
while (totFrms > 0)
{
    if (totFrms < numberFrames)
    {
        numberFrames = totFrms;
        NSLog(@"Final numberFrames :%li",numberFrames);
    }
    else
    {
        totFrms -= numberFrames;
    }
    AudioBufferList *bufferList = (AudioBufferList*)malloc(sizeof(AudioBufferList)+sizeof(AudioBuffer)*(channelCount-1));
    bufferList->mNumberBuffers = channelCount;
    for (int j=0; j<channelCount; j++)
    {
        AudioBuffer buffer = {0};
        buffer.mNumberChannels = 1;
        buffer.mDataByteSize = numberFrames*sizeof(AudioUnitSampleType);
        buffer.mData = calloc(numberFrames, sizeof(AudioUnitSampleType));

        bufferList->mBuffers[j] = buffer;

    }
    CheckError(AudioUnitRender(mGIO,
                               &flags,
                               &inTimeStamp,
                               busNumber,
                               numberFrames,
                               bufferList),
               "AudioUnitRender mGIO");



    CheckError(ExtAudioFileWrite(extAudioFile, numberFrames, bufferList),("extaudiofilewrite fail"));

}

[self FilesSavingCompleted];
}

//文件保存完成

-(void)FilesSavingCompleted{
OSStatus status = ExtAudioFileDispose(extAudioFile);
printf("OSStatus(ExtAudioFileDispose): %ld\n", status);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

核心音频离线渲染GenericOutput 的相关文章

  • 从服务器实时更新的 iOS 应用程序:Socket(使用流)还是 Apple 推送通知服务?

    我正在尝试制作一个 iOS 5 应用程序 该应用程序具有来自服务器的实时信息 它只会在应用程序运行时使用这些 为了使其实时且无需轮询 我一直在评估两种设计路线 创建从应用程序到服务器的套接字 并通过流交换信息 Pros 相对简单 不涉及第三
  • 如何在 iOS 上删除配对的蓝牙设备?

    我希望我的应用程序可以删除配对的蓝牙设备 因为如果设备与 iPhone 配对 则该设备无法用于其他设备 我尝试了 CBCentralManager cancelPeripheralConnection 但它不起作用 他们仍然配对 或者还有其
  • 带过滤器的 AudioKit 导出文件

    我想用音频套件的许多过滤器覆盖现有的 m4a 文件 我的代码 file try AKAudioFile forReading recordVoiceURL player AKPlayer audioFile file delay AKVar
  • 如何在 Xcode 4.5 中添加旧版本的 iOS SDK

    我在这里复制了 iOS 5 1 SDK 应用程序 Xcode app Contents Developer Platforms iPhoneOS platform Developer SDKs 但是 我仍然无法在 Xcode 中选择基础 S
  • scrollViewDidScroll:在 UITableViewRowAnimation 上?

    当一个人使用一个UITableViewRowAnimation删除一行或添加一行时 有时如果该行位于表视图的最末端 则表会滚动 然而 即使它滚动它似乎并没有调用scrollViewDidScroll 关于代表 例如 我的委托中有以下代码 v
  • Swift 3:将 UIButton 扩展添加到 ViewController

    我是 iOS Swift 的初学者 尝试创建一个没有 Storyboard 的简单应用程序 我创建了一个UIButton扩展名 我想在我的视图中添加一个简单的按钮 稍后将设置约束 不幸的是 该按钮不可见 如果有人帮助我 我将不胜感激 谢谢你
  • 函数“FBSDK_NOT_DESIGNATED_INITIALIZER”的隐式声明在 C99 中无效预期“)”

    我正在使用适用于 iOS 4 6 0 的 Facebook SDK 今天将 cocoapods 更新到 0 38 2 后遇到了上述错误 我不确定这个错误与 cocoapods 有什么关系 Error screenshot 我遇到过同样的问题
  • object_setClass()而不是分配isa指针的性能

    我注意到在 XCode 4 6 的最新更新中 我收到了关于以下几行的警告JSONKit m 具体来说 设置对象类的行 dictionary gt isa JKDictionaryClass 这些被标记为已弃用 并注明首选方法是使用objec
  • Swift 和 Objective-C 框架公开其内部结构

    我正在尝试将 Swift 添加到具有公共 私有和项目文件的现有 Objective C 框架中 为了让 Swift 能够访问项目文件 我添加了一个定义新模块的模块映射 例如MyFramework Internal 通过包含所有项目标题 如下
  • 如何在 iOS 上的视图之间进行展开/收缩转换?

    我正在尝试在 iOS 中制作过渡动画 其中视图或视图控制器似乎扩展以填充整个屏幕 然后在完成后收缩回原来的位置 我不确定这种类型的转换的正式名称是什么 但您可以在 iPad 版 YouTube 应用中查看示例 当您点击网格上的搜索结果缩略图
  • 从 Google/Facebook 帐户重新验证用户身份

    因此 我需要创建一个 REST API 来为 IOS 应用程序提供功能 我们允许用户仅使用普通帐户或使用脸书 谷歌登录 我最近一直在阅读 OAuth 我想我了解在我的情况下如何使用 OAuth 的过程 当用户使用脸书 谷歌登录 在我的应用程
  • 平板电脑在第一次单击时悬停,在第二次单击时单击

    发布这个问题主要是希望证实我对该行为的怀疑 从而为其他程序员记录下来 因为我在网上没有找到任何记录 我正在构建一个网站 其导航栏具有以下属性 水平截面是 ul of li 和一些 li li s 两者都有 A n a 元素带您进入该主题 触
  • 即席分发失败

    我在一家大公司工作 正在开发一个适用于 iOS 5 的 iOS 应用程序 分发应用程序的唯一方式是通过临时部署 我拥有自己的服务器已经有一段时间了 由 o2switch 法国托管商 托管 当我开始开发时 我们使用它来部署应用程序以进行 Be
  • 将 HTML 字符串加载到 UIWebView 中的延迟

    我在导航控制器中有两个视图控制器 第一个视图控制器有一个带有按钮的菜单 按下此按钮将移动到第二个视图控制器并将 html 字符串加载到 UIWebView 中 没有其他东西被加载到 webview 中 只是一个简单的 NSString 其中
  • 未安装的应用程序的URL方案

    简单的问题 我正在开发一个将注册自己的 URL 方案的应用程序 我计划通过人们最喜欢的 QRCode 阅读器使用 QRCode 启动该应用程序 我的问题 如果我的应用程序尚未安装在他们的 iPhone iPad 上 会发生什么 他们会被引导
  • 处理核心数据中的重复条目

    我有一个允许用户保存收藏夹的应用程序 我正在使用 Core Data 将收藏夹存储为托管对象 我已经编写了一些代码来防止存储重复项的可能性 但我想知道是否有更好的方法来做到这一点 每个收藏夹对象都有一个唯一的 ID 字段 在下面的代码中 我
  • Xcode 本地化设置中没有加号或减号按钮

    我需要在两天内翻译 iOS 应用程序 但我的 XCode 版本 4 4 和 4 5 Developer Preview 都没有给我添加其他语言的选项 我只能选择单击 Make localized 但我只能选择英语 选择它后 Xcode 中的
  • iOS:addConstraints:应用程序崩溃

    Problem 我似乎无法在现有项目中采用自动布局 Details 我之前也遇到过与此问题相同的问题presentViewController 在 iOS 但所提供的答案都不是我的解决方案 我正在使用所有没有 xib 的故事板视图 我的 使
  • 如何在 XCode5 中将部署目标更改为 5.1.1 [重复]

    这个问题在这里已经有答案了 我正在一个项目中工作 我需要支持 iOS 5 1 1 但在 部署目标 的下拉菜单中我没有 5 1 1 作为选项 我的问题是如何将 iOS 5 1 1 添加为部署目标 我将非常感谢你的帮助 如果您愿意 您可以在框中
  • NSURLConnection 是否自动保留从服务器发送的 cookie?

    我从 ios 登录到我的龙卷风后端并发回 secure cookie 我注意到只要验证我设置的 secure cookie 我还可以请求其他信息 NSURLConnection 会保留 cookie 多久 或者关闭应用程序后 cookie

随机推荐

  • 单击用户控件时如何防止窃取焦点? [复制]

    这个问题在这里已经有答案了 我希望能够单击我的用户控件 而不让它从任何其他控件中窃取焦点 我知道当你点击标签时它不会夺走焦点 如何才能做到这一点 尝试禁用您的控件ControlStyles Selectable http msdn micr
  • 如何在通过 Laravel Eloquent 方法连接的元素上使用 orderby

    问题是查询无法找到应该与 Laravel Eloquent 中的方法WITH 连接的特定方法 特定方法 特定模型 特定模型 特定方法等 有什么想法如何解决吗 我的代码 SpecificModel
  • Android 中自定义对话框内的日期选择器

    我想在自定义对话框中使用日期选择器 单击按钮上的日历将打开以供用户选择日期 我的 customDilaog 类中有 Button 在该按钮上单击 我想打开日历视图 如果单击此按钮 我的应用程序将崩溃 我已经完成了这个 CustomDialo
  • 在 Interface Builder 中添加背景图像

    我正在尝试使用 Xcode 4 2 添加自定义图像作为我的应用程序的背景 但我不太确定该怎么做 我可以在 Interface Builder 中添加纯色作为背景 但我没有看到添加自定义图像的选项 我在谷歌上搜索了这个问题并研究了几个小时 但
  • 逆变方法参数类型

    wiki 逆变方法参数类型 https en wikipedia org wiki Covariance and contravariance 28computer science 29 Contravariant method argum
  • 为什么我们从 MultiByte 转换为 WideChar?

    我习惯于处理 ASCII 字符串 但现在使用 UNICODE 我对一些术语感到非常困惑 什么是多字节字符以及什么是widechar有什么不同 多字节是指在内存中包含多个字节的字符吗 widechar只是一个数据类型来表示吗 为什么我们要从M
  • Angular:DOM更新后调用方法

    我正在从 html 调用一个方法 调用休息服务 来增加 减少屏幕上的计数 现在我想调用另一个方法 即 getThreshold 来检查计数是否达到阈值 如果是 我想显示一条确认消息 我想首先更新屏幕上的计数 然后调用该函数来检查它是否达到阈
  • 在 Jenkins 中执行批处理文件

    我有一个简单的批处理文件 我想要从 Jenkins 调用 运行 执行该文件 Jenkins 中有同样的插件吗 如何从 Jenkins 执行批处理文件 如果有相同的教程或文档 无需为此添加新插件 在Jenkins 选择您的工作名称并转到配置部
  • 可以以编程方式打开“立即发言”对话框吗?

    是否可以通过编程方式打开 立即发言 对话框 目前 如果用户点击我的 搜索 按钮 则会打开一个对话框 并且我会自动打开软键盘 因此用户无需点击文本编辑字段 我想提供一个替代的 通过语音搜索 它将打开对话框并自动打开 立即发言 窗口 因此用户不
  • JsonNode findValue 不搜索子节点

    我有一个结构如下的资源 activity activity type Like activity id 123456 object id product id reference activity activity type Rating
  • 如何在@FacesConverter中注入@EJB、@PersistenceContext、@Inject、@Autowired等?

    我怎样才能注入像这样的依赖项 EJB PersistenceContext Inject AutoWired等在一个 FacesConverter 在我的具体情况下 我需要通过注入 EJB EJB FacesConverter public
  • android中自动启动一个新的activity

    我正在创建一个 Android 应用程序 我有一个logo screen Activity 然后我的home screen another activity 我希望当我启动应用程序时 我的徽标屏幕应该出现 然后 2 秒后自动出现我的主屏幕
  • Ansible 创建可以访问所有表的 postgresql 用户?

    这应该很简单 我想要创建一个 Ansible 语句来创建一个 Postgres 用户 该用户具有特定数据库的连接权限以及对该特定数据库中所有表的选择 插入 更新 删除权限 我尝试了以下方法 name Create postgres user
  • 缩放插图中不同的 x 和 y 比例,matplotlib

    我正在尝试使用 matplotlib 制作插图 目前我有类似最后一个答案的内容如何缩放图像的一部分并插入到 matplotlib 中的同一图中 https stackoverflow com questions 13583153 how t
  • java中的^运算符[重复]

    这个问题在这里已经有答案了 谁能用一些例子解释一下java中 运算符的使用 这与大多数语言中的 相同 只是异或 false false false true false true false true true true true fals
  • 当我想要发布项目时:“指定的路径、文件名或两者都太长”

    当我想运行或发布网络项目时 我收到此错误 严重性代码 说明 项目文件行抑制状态 错误 无法评估项目元数据 FullPath 项目元数据 FullPath 无法应用于路径 jquery ui 1 10 3 custom development
  • Nunit 测试给出结果 OneTimeSetUp: 未找到合适的构造函数

    我有一个问题 NUnit 告诉我 没有找到合适的构造函数 这是什么原因造成的 我还收到另一条消息 异常没有堆栈跟踪 这两条消息只是一遍又一遍地重复 这是我的代码 TestFixture public class SecurityServic
  • 在 Raspberry Pi 4 上的多个输出设备上播放多个 mp3 文件

    我需要 4 8 个同时播放立体声音频音乐频道 连续播放 SD 卡上特定文件夹中的 mp3 音乐 Working 板载 3 5 音频插孔 USB声卡正常播放音乐 Problem 但一旦我尝试在树莓派上使用带有 USB 声卡的第三个音频输出 其
  • C# 4.0 动态对象和 WinAPI 接口,如 IShellItem(无需在 C# 源代码中定义它们)

    是否可以 使用 C 4 0 中的新动态关键字 使用接口 如 IShellItem 或其他 WinAPI 接口 而无需在 C 源代码中定义它们 或者至少不定义接口成员 我正在尝试类似的事情 const string IShellItemGui
  • 核心音频离线渲染GenericOutput

    有人使用 core Audio 成功完成离线渲染吗 我必须混合两个音频文件并应用混响 使用 2 AudioFilePlayer MultiChannelMixer Reverb2 和 RemoteIO 成功了 我可以在预览时保存它 在 Re